xref: /titanic_50/usr/src/uts/common/io/nge/nge_chip.c (revision 51fc88a818087605a0e5f11eddb8b66576f72c23)
16f3e57acSmx205022 /*
247693af9Smx205022  * CDDL HEADER START
347693af9Smx205022  *
447693af9Smx205022  * The contents of this file are subject to the terms of the
547693af9Smx205022  * Common Development and Distribution License (the "License").
647693af9Smx205022  * You may not use this file except in compliance with the License.
747693af9Smx205022  *
847693af9Smx205022  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
947693af9Smx205022  * or http://www.opensolaris.org/os/licensing.
1047693af9Smx205022  * See the License for the specific language governing permissions
1147693af9Smx205022  * and limitations under the License.
1247693af9Smx205022  *
1347693af9Smx205022  * When distributing Covered Code, include this CDDL HEADER in each
1447693af9Smx205022  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1547693af9Smx205022  * If applicable, add the following below this CDDL HEADER, with the
1647693af9Smx205022  * fields enclosed by brackets "[]" replaced with your own identifying
1747693af9Smx205022  * information: Portions Copyright [yyyy] [name of copyright owner]
1847693af9Smx205022  *
1947693af9Smx205022  * CDDL HEADER END
206f3e57acSmx205022  */
216f3e57acSmx205022 
226f3e57acSmx205022 /*
23d635b452SWinson Wang - Sun Microsystems - Beijing China  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2447693af9Smx205022  * Use is subject to license terms.
256f3e57acSmx205022  */
266f3e57acSmx205022 
276f3e57acSmx205022 #include "nge.h"
28*51fc88a8SWinson Wang - Sun Microsystems - Beijing China static uint32_t	nge_watchdog_count	= 1 << 5;
29*51fc88a8SWinson Wang - Sun Microsystems - Beijing China static uint32_t	nge_watchdog_check	= 1 << 3;
306f3e57acSmx205022 extern boolean_t nge_enable_msi;
316f3e57acSmx205022 static void nge_sync_mac_modes(nge_t *);
326f3e57acSmx205022 
336f3e57acSmx205022 #undef NGE_DBG
346f3e57acSmx205022 #define	NGE_DBG		NGE_DBG_CHIP
356f3e57acSmx205022 
366f3e57acSmx205022 /*
376f3e57acSmx205022  * Operating register get/set access routines
386f3e57acSmx205022  */
396f3e57acSmx205022 uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno);
406f3e57acSmx205022 #pragma	inline(nge_reg_get8)
416f3e57acSmx205022 
426f3e57acSmx205022 uint8_t
nge_reg_get8(nge_t * ngep,nge_regno_t regno)436f3e57acSmx205022 nge_reg_get8(nge_t *ngep, nge_regno_t regno)
446f3e57acSmx205022 {
456f3e57acSmx205022 	NGE_TRACE(("nge_reg_get8($%p, 0x%lx)", (void *)ngep, regno));
466f3e57acSmx205022 
476f3e57acSmx205022 	return (ddi_get8(ngep->io_handle, PIO_ADDR(ngep, regno)));
486f3e57acSmx205022 }
496f3e57acSmx205022 
506f3e57acSmx205022 void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data);
516f3e57acSmx205022 #pragma	inline(nge_reg_put8)
526f3e57acSmx205022 
536f3e57acSmx205022 void
nge_reg_put8(nge_t * ngep,nge_regno_t regno,uint8_t data)546f3e57acSmx205022 nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data)
556f3e57acSmx205022 {
566f3e57acSmx205022 	NGE_TRACE(("nge_reg_put8($%p, 0x%lx, 0x%x)",
576f3e57acSmx205022 	    (void *)ngep, regno, data));
586f3e57acSmx205022 	ddi_put8(ngep->io_handle, PIO_ADDR(ngep, regno), data);
596f3e57acSmx205022 
606f3e57acSmx205022 }
616f3e57acSmx205022 
626f3e57acSmx205022 uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno);
636f3e57acSmx205022 #pragma	inline(nge_reg_get16)
646f3e57acSmx205022 
656f3e57acSmx205022 uint16_t
nge_reg_get16(nge_t * ngep,nge_regno_t regno)666f3e57acSmx205022 nge_reg_get16(nge_t *ngep, nge_regno_t regno)
676f3e57acSmx205022 {
686f3e57acSmx205022 	NGE_TRACE(("nge_reg_get16($%p, 0x%lx)", (void *)ngep, regno));
696f3e57acSmx205022 	return (ddi_get16(ngep->io_handle, PIO_ADDR(ngep, regno)));
706f3e57acSmx205022 }
716f3e57acSmx205022 
726f3e57acSmx205022 void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
736f3e57acSmx205022 #pragma	inline(nge_reg_put16)
746f3e57acSmx205022 
756f3e57acSmx205022 void
nge_reg_put16(nge_t * ngep,nge_regno_t regno,uint16_t data)766f3e57acSmx205022 nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data)
776f3e57acSmx205022 {
786f3e57acSmx205022 	NGE_TRACE(("nge_reg_put16($%p, 0x%lx, 0x%x)",
796f3e57acSmx205022 	    (void *)ngep, regno, data));
806f3e57acSmx205022 	ddi_put16(ngep->io_handle, PIO_ADDR(ngep, regno), data);
816f3e57acSmx205022 
826f3e57acSmx205022 }
836f3e57acSmx205022 
846f3e57acSmx205022 uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno);
856f3e57acSmx205022 #pragma	inline(nge_reg_get32)
866f3e57acSmx205022 
876f3e57acSmx205022 uint32_t
nge_reg_get32(nge_t * ngep,nge_regno_t regno)886f3e57acSmx205022 nge_reg_get32(nge_t *ngep, nge_regno_t regno)
896f3e57acSmx205022 {
906f3e57acSmx205022 	NGE_TRACE(("nge_reg_get32($%p, 0x%lx)", (void *)ngep, regno));
916f3e57acSmx205022 	return (ddi_get32(ngep->io_handle, PIO_ADDR(ngep, regno)));
926f3e57acSmx205022 }
936f3e57acSmx205022 
946f3e57acSmx205022 void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data);
956f3e57acSmx205022 #pragma	inline(nge_reg_put32)
966f3e57acSmx205022 
976f3e57acSmx205022 void
nge_reg_put32(nge_t * ngep,nge_regno_t regno,uint32_t data)986f3e57acSmx205022 nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data)
996f3e57acSmx205022 {
1006f3e57acSmx205022 	NGE_TRACE(("nge_reg_put32($%p, 0x%lx, 0x%x)",
1016f3e57acSmx205022 	    (void *)ngep, regno, data));
1026f3e57acSmx205022 	ddi_put32(ngep->io_handle, PIO_ADDR(ngep, regno), data);
1036f3e57acSmx205022 
1046f3e57acSmx205022 }
1056f3e57acSmx205022 
1066f3e57acSmx205022 
1076f3e57acSmx205022 static int nge_chip_peek_cfg(nge_t *ngep, nge_peekpoke_t *ppd);
1086f3e57acSmx205022 #pragma	no_inline(nge_chip_peek_cfg)
1096f3e57acSmx205022 
1106f3e57acSmx205022 static int
nge_chip_peek_cfg(nge_t * ngep,nge_peekpoke_t * ppd)1116f3e57acSmx205022 nge_chip_peek_cfg(nge_t *ngep, nge_peekpoke_t *ppd)
1126f3e57acSmx205022 {
1136f3e57acSmx205022 	int err;
1146f3e57acSmx205022 	uint64_t regval;
1156f3e57acSmx205022 	uint64_t regno;
1166f3e57acSmx205022 
1176f3e57acSmx205022 	NGE_TRACE(("nge_chip_peek_cfg($%p, $%p)",
1186f3e57acSmx205022 	    (void *)ngep, (void *)ppd));
1196f3e57acSmx205022 
1206f3e57acSmx205022 	err = DDI_SUCCESS;
1216f3e57acSmx205022 	regno = ppd->pp_acc_offset;
1226f3e57acSmx205022 
1236f3e57acSmx205022 	switch (ppd->pp_acc_size) {
1246f3e57acSmx205022 	case 1:
1256f3e57acSmx205022 		regval = pci_config_get8(ngep->cfg_handle, regno);
1266f3e57acSmx205022 		break;
1276f3e57acSmx205022 
1286f3e57acSmx205022 	case 2:
1296f3e57acSmx205022 		regval = pci_config_get16(ngep->cfg_handle, regno);
1306f3e57acSmx205022 		break;
1316f3e57acSmx205022 
1326f3e57acSmx205022 	case 4:
1336f3e57acSmx205022 		regval = pci_config_get32(ngep->cfg_handle, regno);
1346f3e57acSmx205022 		break;
1356f3e57acSmx205022 
1366f3e57acSmx205022 	case 8:
1376f3e57acSmx205022 		regval = pci_config_get64(ngep->cfg_handle, regno);
1386f3e57acSmx205022 		break;
1396f3e57acSmx205022 	}
1406f3e57acSmx205022 	ppd->pp_acc_data = regval;
1416f3e57acSmx205022 	return (err);
1426f3e57acSmx205022 }
1436f3e57acSmx205022 
1446f3e57acSmx205022 static int nge_chip_poke_cfg(nge_t *ngep, nge_peekpoke_t *ppd);
1456f3e57acSmx205022 
1466f3e57acSmx205022 static int
nge_chip_poke_cfg(nge_t * ngep,nge_peekpoke_t * ppd)1476f3e57acSmx205022 nge_chip_poke_cfg(nge_t *ngep, nge_peekpoke_t *ppd)
1486f3e57acSmx205022 {
1496f3e57acSmx205022 	int err;
1506f3e57acSmx205022 	uint64_t regval;
1516f3e57acSmx205022 	uint64_t regno;
1526f3e57acSmx205022 
1536f3e57acSmx205022 	NGE_TRACE(("nge_chip_poke_cfg($%p, $%p)",
1546f3e57acSmx205022 	    (void *)ngep, (void *)ppd));
1556f3e57acSmx205022 
1566f3e57acSmx205022 	err = DDI_SUCCESS;
1576f3e57acSmx205022 	regno = ppd->pp_acc_offset;
1586f3e57acSmx205022 	regval = ppd->pp_acc_data;
1596f3e57acSmx205022 
1606f3e57acSmx205022 	switch (ppd->pp_acc_size) {
1616f3e57acSmx205022 	case 1:
1626f3e57acSmx205022 		pci_config_put8(ngep->cfg_handle, regno, regval);
1636f3e57acSmx205022 		break;
1646f3e57acSmx205022 
1656f3e57acSmx205022 	case 2:
1666f3e57acSmx205022 		pci_config_put16(ngep->cfg_handle, regno, regval);
1676f3e57acSmx205022 		break;
1686f3e57acSmx205022 
1696f3e57acSmx205022 	case 4:
1706f3e57acSmx205022 		pci_config_put32(ngep->cfg_handle, regno, regval);
1716f3e57acSmx205022 		break;
1726f3e57acSmx205022 
1736f3e57acSmx205022 	case 8:
1746f3e57acSmx205022 		pci_config_put64(ngep->cfg_handle, regno, regval);
1756f3e57acSmx205022 		break;
1766f3e57acSmx205022 	}
1776f3e57acSmx205022 
1786f3e57acSmx205022 	return (err);
1796f3e57acSmx205022 
1806f3e57acSmx205022 }
1816f3e57acSmx205022 
1826f3e57acSmx205022 static int nge_chip_peek_reg(nge_t *ngep, nge_peekpoke_t *ppd);
1836f3e57acSmx205022 
1846f3e57acSmx205022 static int
nge_chip_peek_reg(nge_t * ngep,nge_peekpoke_t * ppd)1856f3e57acSmx205022 nge_chip_peek_reg(nge_t *ngep, nge_peekpoke_t *ppd)
1866f3e57acSmx205022 {
1876f3e57acSmx205022 	int err;
1886f3e57acSmx205022 	uint64_t regval;
1896f3e57acSmx205022 	void *regaddr;
1906f3e57acSmx205022 
1916f3e57acSmx205022 	NGE_TRACE(("nge_chip_peek_reg($%p, $%p)",
1926f3e57acSmx205022 	    (void *)ngep, (void *)ppd));
1936f3e57acSmx205022 
1946f3e57acSmx205022 	err = DDI_SUCCESS;
1956f3e57acSmx205022 	regaddr = PIO_ADDR(ngep, ppd->pp_acc_offset);
1966f3e57acSmx205022 
1976f3e57acSmx205022 	switch (ppd->pp_acc_size) {
1986f3e57acSmx205022 	case 1:
1996f3e57acSmx205022 		regval = ddi_get8(ngep->io_handle, regaddr);
2006f3e57acSmx205022 	break;
2016f3e57acSmx205022 
2026f3e57acSmx205022 	case 2:
2036f3e57acSmx205022 		regval = ddi_get16(ngep->io_handle, regaddr);
2046f3e57acSmx205022 	break;
2056f3e57acSmx205022 
2066f3e57acSmx205022 	case 4:
2076f3e57acSmx205022 		regval = ddi_get32(ngep->io_handle, regaddr);
2086f3e57acSmx205022 	break;
2096f3e57acSmx205022 
2106f3e57acSmx205022 	case 8:
2116f3e57acSmx205022 		regval = ddi_get64(ngep->io_handle, regaddr);
2126f3e57acSmx205022 	break;
2136f3e57acSmx205022 
2146f3e57acSmx205022 	default:
2156f3e57acSmx205022 		regval = 0x0ull;
2166f3e57acSmx205022 	break;
2176f3e57acSmx205022 	}
2186f3e57acSmx205022 	ppd->pp_acc_data = regval;
2196f3e57acSmx205022 	return (err);
2206f3e57acSmx205022 }
2216f3e57acSmx205022 
2226f3e57acSmx205022 static int nge_chip_poke_reg(nge_t *ngep, nge_peekpoke_t *ppd);
2236f3e57acSmx205022 
2246f3e57acSmx205022 static int
nge_chip_poke_reg(nge_t * ngep,nge_peekpoke_t * ppd)2256f3e57acSmx205022 nge_chip_poke_reg(nge_t *ngep, nge_peekpoke_t *ppd)
2266f3e57acSmx205022 {
2276f3e57acSmx205022 	int err;
2286f3e57acSmx205022 	uint64_t regval;
2296f3e57acSmx205022 	void *regaddr;
2306f3e57acSmx205022 
2316f3e57acSmx205022 	NGE_TRACE(("nge_chip_poke_reg($%p, $%p)",
2326f3e57acSmx205022 	    (void *)ngep, (void *)ppd));
2336f3e57acSmx205022 
2346f3e57acSmx205022 	err = DDI_SUCCESS;
2356f3e57acSmx205022 	regaddr = PIO_ADDR(ngep, ppd->pp_acc_offset);
2366f3e57acSmx205022 	regval = ppd->pp_acc_data;
2376f3e57acSmx205022 
2386f3e57acSmx205022 	switch (ppd->pp_acc_size) {
2396f3e57acSmx205022 	case 1:
2406f3e57acSmx205022 		ddi_put8(ngep->io_handle, regaddr, regval);
2416f3e57acSmx205022 		break;
2426f3e57acSmx205022 
2436f3e57acSmx205022 	case 2:
2446f3e57acSmx205022 		ddi_put16(ngep->io_handle, regaddr, regval);
2456f3e57acSmx205022 		break;
2466f3e57acSmx205022 
2476f3e57acSmx205022 	case 4:
2486f3e57acSmx205022 		ddi_put32(ngep->io_handle, regaddr, regval);
2496f3e57acSmx205022 		break;
2506f3e57acSmx205022 
2516f3e57acSmx205022 	case 8:
2526f3e57acSmx205022 		ddi_put64(ngep->io_handle, regaddr, regval);
2536f3e57acSmx205022 		break;
2546f3e57acSmx205022 	}
2556f3e57acSmx205022 	return (err);
2566f3e57acSmx205022 }
2576f3e57acSmx205022 
2586f3e57acSmx205022 static int nge_chip_peek_mii(nge_t *ngep, nge_peekpoke_t *ppd);
2596f3e57acSmx205022 #pragma	no_inline(nge_chip_peek_mii)
2606f3e57acSmx205022 
2616f3e57acSmx205022 static int
nge_chip_peek_mii(nge_t * ngep,nge_peekpoke_t * ppd)2626f3e57acSmx205022 nge_chip_peek_mii(nge_t *ngep, nge_peekpoke_t *ppd)
2636f3e57acSmx205022 {
2646f3e57acSmx205022 	int err;
2656f3e57acSmx205022 
2666f3e57acSmx205022 	err = DDI_SUCCESS;
2676f3e57acSmx205022 	ppd->pp_acc_data = nge_mii_get16(ngep, ppd->pp_acc_offset/2);
2686f3e57acSmx205022 	return (err);
2696f3e57acSmx205022 }
2706f3e57acSmx205022 
2716f3e57acSmx205022 static int nge_chip_poke_mii(nge_t *ngep, nge_peekpoke_t *ppd);
2726f3e57acSmx205022 #pragma	no_inline(nge_chip_poke_mii)
2736f3e57acSmx205022 
2746f3e57acSmx205022 static int
nge_chip_poke_mii(nge_t * ngep,nge_peekpoke_t * ppd)2756f3e57acSmx205022 nge_chip_poke_mii(nge_t *ngep, nge_peekpoke_t *ppd)
2766f3e57acSmx205022 {
2776f3e57acSmx205022 	int err;
2786f3e57acSmx205022 	err = DDI_SUCCESS;
2796f3e57acSmx205022 	nge_mii_put16(ngep, ppd->pp_acc_offset/2, ppd->pp_acc_data);
2806f3e57acSmx205022 	return (err);
2816f3e57acSmx205022 }
2826f3e57acSmx205022 
2836f3e57acSmx205022 /*
2846f3e57acSmx205022  * Basic SEEPROM get/set access routine
2856f3e57acSmx205022  *
2866f3e57acSmx205022  * This uses the chip's SEEPROM auto-access method, controlled by the
2876f3e57acSmx205022  * Serial EEPROM Address/Data Registers at 0x504h, so the CPU
2886f3e57acSmx205022  * doesn't have to fiddle with the individual bits.
2896f3e57acSmx205022  *
2906f3e57acSmx205022  * The caller should hold <genlock> and *also* have already acquired
2916f3e57acSmx205022  * the right to access the SEEPROM.
2926f3e57acSmx205022  *
2936f3e57acSmx205022  * Return value:
2946f3e57acSmx205022  *	0 on success,
2956f3e57acSmx205022  *	ENODATA on access timeout (maybe retryable: device may just be busy)
2966f3e57acSmx205022  *	EPROTO on other h/w or s/w errors.
2976f3e57acSmx205022  *
2986f3e57acSmx205022  * <*dp> is an input to a SEEPROM_ACCESS_WRITE operation, or an output
2996f3e57acSmx205022  * from a (successful) SEEPROM_ACCESS_READ.
3006f3e57acSmx205022  */
3016f3e57acSmx205022 
3026f3e57acSmx205022 static int
nge_seeprom_access(nge_t * ngep,uint32_t cmd,nge_regno_t addr,uint16_t * dp)3036f3e57acSmx205022 nge_seeprom_access(nge_t *ngep, uint32_t cmd, nge_regno_t addr, uint16_t *dp)
3046f3e57acSmx205022 {
3056f3e57acSmx205022 	uint32_t tries;
3066f3e57acSmx205022 	nge_ep_cmd cmd_reg;
3076f3e57acSmx205022 	nge_ep_data data_reg;
3086f3e57acSmx205022 
3096f3e57acSmx205022 	NGE_TRACE(("nge_seeprom_access($%p, %d, %x, $%p)",
3106f3e57acSmx205022 	    (void *)ngep, cmd, addr, (void *)dp));
3116f3e57acSmx205022 
3126f3e57acSmx205022 	ASSERT(mutex_owned(ngep->genlock));
3136f3e57acSmx205022 
3146f3e57acSmx205022 	/*
3156f3e57acSmx205022 	 * Check there's no command in progress.
3166f3e57acSmx205022 	 *
3176f3e57acSmx205022 	 * Note: this *shouldn't* ever find that there is a command
3186f3e57acSmx205022 	 * in progress, because we already hold the <genlock> mutex.
3196f3e57acSmx205022 	 * Also, to ensure we don't have a conflict with the chip's
3206f3e57acSmx205022 	 * internal firmware or a process accessing the same (shared)
3216f3e57acSmx205022 	 * So this is just a final consistency check: we shouldn't
3226f3e57acSmx205022 	 * see EITHER the START bit (command started but not complete)
3236f3e57acSmx205022 	 * OR the COMPLETE bit (command completed but not cleared).
3246f3e57acSmx205022 	 */
3256f3e57acSmx205022 	cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
3266f3e57acSmx205022 	for (tries = 0; tries < 30; tries++) {
3276f3e57acSmx205022 		if (cmd_reg.cmd_bits.sts == SEEPROM_READY)
3286f3e57acSmx205022 			break;
3296f3e57acSmx205022 		drv_usecwait(10);
3306f3e57acSmx205022 		cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
3316f3e57acSmx205022 	}
3326f3e57acSmx205022 
3336f3e57acSmx205022 	/*
3346f3e57acSmx205022 	 * This should not happen. If so, we have to restart eeprom
3356f3e57acSmx205022 	 *  state machine
3366f3e57acSmx205022 	 */
3376f3e57acSmx205022 	if (tries == 30) {
3386f3e57acSmx205022 		cmd_reg.cmd_bits.sts = SEEPROM_READY;
3396f3e57acSmx205022 		nge_reg_put32(ngep, NGE_EP_CMD, cmd_reg.cmd_val);
3406f3e57acSmx205022 		drv_usecwait(10);
3416f3e57acSmx205022 		/*
3426f3e57acSmx205022 		 * Polling the status bit to make assure the eeprom is ready
3436f3e57acSmx205022 		 */
3446f3e57acSmx205022 		cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
3456f3e57acSmx205022 		for (tries = 0; tries < 30; tries++) {
3466f3e57acSmx205022 			if (cmd_reg.cmd_bits.sts == SEEPROM_READY)
3476f3e57acSmx205022 				break;
3486f3e57acSmx205022 			drv_usecwait(10);
3496f3e57acSmx205022 			cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
3506f3e57acSmx205022 		}
3516f3e57acSmx205022 	}
3526f3e57acSmx205022 
3536f3e57acSmx205022 	/*
3546f3e57acSmx205022 	 * Assemble the command ...
3556f3e57acSmx205022 	 */
356a55f7119SMiles Xu, Sun Microsystems 	cmd_reg.cmd_bits.addr = (uint32_t)addr;
3576f3e57acSmx205022 	cmd_reg.cmd_bits.cmd = cmd;
3586f3e57acSmx205022 	cmd_reg.cmd_bits.sts = 0;
3596f3e57acSmx205022 
3606f3e57acSmx205022 	nge_reg_put32(ngep, NGE_EP_CMD, cmd_reg.cmd_val);
3616f3e57acSmx205022 
3626f3e57acSmx205022 	/*
3636f3e57acSmx205022 	 * Polling whether the access is successful.
3646f3e57acSmx205022 	 *
3656f3e57acSmx205022 	 */
3666f3e57acSmx205022 	cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
3676f3e57acSmx205022 	for (tries = 0; tries < 30; tries++) {
3686f3e57acSmx205022 		if (cmd_reg.cmd_bits.sts == SEEPROM_READY)
3696f3e57acSmx205022 			break;
3706f3e57acSmx205022 		drv_usecwait(10);
3716f3e57acSmx205022 		cmd_reg.cmd_val = nge_reg_get32(ngep, NGE_EP_CMD);
3726f3e57acSmx205022 	}
3736f3e57acSmx205022 
3746f3e57acSmx205022 	if (tries == 30) {
3756f3e57acSmx205022 		nge_report(ngep, NGE_HW_ROM);
3766f3e57acSmx205022 		return (DDI_FAILURE);
3776f3e57acSmx205022 	}
3786f3e57acSmx205022 	switch (cmd) {
3796f3e57acSmx205022 	default:
3806f3e57acSmx205022 	case SEEPROM_CMD_WRITE_ENABLE:
3816f3e57acSmx205022 	case SEEPROM_CMD_ERASE:
3826f3e57acSmx205022 	case SEEPROM_CMD_ERALSE_ALL:
3836f3e57acSmx205022 	case SEEPROM_CMD_WRITE_DIS:
3846f3e57acSmx205022 	break;
3856f3e57acSmx205022 
3866f3e57acSmx205022 	case SEEPROM_CMD_READ:
3876f3e57acSmx205022 		data_reg.data_val = nge_reg_get32(ngep, NGE_EP_DATA);
3886f3e57acSmx205022 		*dp = data_reg.data_bits.data;
3896f3e57acSmx205022 	break;
3906f3e57acSmx205022 
3916f3e57acSmx205022 	case SEEPROM_CMD_WRITE:
3926f3e57acSmx205022 		data_reg.data_val = nge_reg_get32(ngep, NGE_EP_DATA);
3936f3e57acSmx205022 		data_reg.data_bits.data = *dp;
3946f3e57acSmx205022 		nge_reg_put32(ngep, NGE_EP_DATA, data_reg.data_val);
3956f3e57acSmx205022 	break;
3966f3e57acSmx205022 	}
3976f3e57acSmx205022 
3986f3e57acSmx205022 	return (DDI_SUCCESS);
3996f3e57acSmx205022 }
4006f3e57acSmx205022 
4016f3e57acSmx205022 
4026f3e57acSmx205022 static int
nge_chip_peek_seeprom(nge_t * ngep,nge_peekpoke_t * ppd)4036f3e57acSmx205022 nge_chip_peek_seeprom(nge_t *ngep, nge_peekpoke_t *ppd)
4046f3e57acSmx205022 {
4056f3e57acSmx205022 	uint16_t data;
4066f3e57acSmx205022 	int err;
4076f3e57acSmx205022 
4086f3e57acSmx205022 	err = nge_seeprom_access(ngep, SEEPROM_CMD_READ,
4096f3e57acSmx205022 	    ppd->pp_acc_offset, &data);
4106f3e57acSmx205022 	ppd->pp_acc_data =  data;
4116f3e57acSmx205022 	return (err);
4126f3e57acSmx205022 }
4136f3e57acSmx205022 
4146f3e57acSmx205022 static int
nge_chip_poke_seeprom(nge_t * ngep,nge_peekpoke_t * ppd)4156f3e57acSmx205022 nge_chip_poke_seeprom(nge_t *ngep, nge_peekpoke_t *ppd)
4166f3e57acSmx205022 {
4176f3e57acSmx205022 	uint16_t data;
4186f3e57acSmx205022 	int err;
4196f3e57acSmx205022 
4206f3e57acSmx205022 	data = ppd->pp_acc_data;
4216f3e57acSmx205022 	err = nge_seeprom_access(ngep, SEEPROM_CMD_WRITE,
4226f3e57acSmx205022 	    ppd->pp_acc_offset, &data);
4236f3e57acSmx205022 	return (err);
4246f3e57acSmx205022 }
4256f3e57acSmx205022 
4266f3e57acSmx205022 void
nge_init_dev_spec_param(nge_t * ngep)4276f3e57acSmx205022 nge_init_dev_spec_param(nge_t *ngep)
4286f3e57acSmx205022 {
4296f3e57acSmx205022 	nge_dev_spec_param_t	*dev_param_p;
4306f3e57acSmx205022 	chip_info_t	*infop;
4316f3e57acSmx205022 
4326f3e57acSmx205022 	dev_param_p = &ngep->dev_spec_param;
4336f3e57acSmx205022 	infop = (chip_info_t *)&ngep->chipinfo;
4346f3e57acSmx205022 
4356f3e57acSmx205022 	switch (infop->device) {
4366f3e57acSmx205022 	case DEVICE_ID_NF3_E6:
4376f3e57acSmx205022 	case DEVICE_ID_NF3_DF:
4386f3e57acSmx205022 	case DEVICE_ID_MCP04_37:
4396f3e57acSmx205022 	case DEVICE_ID_MCP04_38:
4406f3e57acSmx205022 		dev_param_p->msi = B_FALSE;
4416f3e57acSmx205022 		dev_param_p->msi_x = B_FALSE;
4426f3e57acSmx205022 		dev_param_p->vlan = B_FALSE;
4439ae6bcf1Sjj146644 		dev_param_p->advanced_pm = B_FALSE;
444d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->mac_addr_order = B_FALSE;
4456f3e57acSmx205022 		dev_param_p->tx_pause_frame = B_FALSE;
4466f3e57acSmx205022 		dev_param_p->rx_pause_frame = B_FALSE;
4476f3e57acSmx205022 		dev_param_p->jumbo = B_FALSE;
4486f3e57acSmx205022 		dev_param_p->tx_rx_64byte = B_FALSE;
4496f3e57acSmx205022 		dev_param_p->rx_hw_checksum = B_FALSE;
4506f3e57acSmx205022 		dev_param_p->tx_hw_checksum = 0;
4516f3e57acSmx205022 		dev_param_p->desc_type = DESC_OFFLOAD;
4526f3e57acSmx205022 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
4536f3e57acSmx205022 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
4546f3e57acSmx205022 		dev_param_p->nge_split = NGE_SPLIT_32;
4556f3e57acSmx205022 		break;
4566f3e57acSmx205022 
4576f3e57acSmx205022 	case DEVICE_ID_CK804_56:
4586f3e57acSmx205022 	case DEVICE_ID_CK804_57:
4596f3e57acSmx205022 		dev_param_p->msi = B_TRUE;
4606f3e57acSmx205022 		dev_param_p->msi_x = B_TRUE;
4616f3e57acSmx205022 		dev_param_p->vlan = B_FALSE;
4629ae6bcf1Sjj146644 		dev_param_p->advanced_pm = B_FALSE;
463d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->mac_addr_order = B_FALSE;
4646f3e57acSmx205022 		dev_param_p->tx_pause_frame = B_FALSE;
4656f3e57acSmx205022 		dev_param_p->rx_pause_frame = B_TRUE;
4666f3e57acSmx205022 		dev_param_p->jumbo = B_TRUE;
4676f3e57acSmx205022 		dev_param_p->tx_rx_64byte = B_FALSE;
4686f3e57acSmx205022 		dev_param_p->rx_hw_checksum = B_TRUE;
4696f3e57acSmx205022 		dev_param_p->tx_hw_checksum = HCKSUM_IPHDRCKSUM;
4706f3e57acSmx205022 		dev_param_p->desc_type = DESC_HOT;
4716f3e57acSmx205022 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_3072;
4726f3e57acSmx205022 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_3072;
4736f3e57acSmx205022 		dev_param_p->nge_split = NGE_SPLIT_96;
4746f3e57acSmx205022 		break;
4756f3e57acSmx205022 
4766f3e57acSmx205022 	case DEVICE_ID_MCP51_268:
4776f3e57acSmx205022 	case DEVICE_ID_MCP51_269:
4786f3e57acSmx205022 		dev_param_p->msi = B_FALSE;
4796f3e57acSmx205022 		dev_param_p->msi_x = B_FALSE;
4806f3e57acSmx205022 		dev_param_p->vlan = B_FALSE;
4819ae6bcf1Sjj146644 		dev_param_p->advanced_pm = B_TRUE;
482d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->mac_addr_order = B_FALSE;
4836f3e57acSmx205022 		dev_param_p->tx_pause_frame = B_FALSE;
4846f3e57acSmx205022 		dev_param_p->rx_pause_frame = B_FALSE;
4856f3e57acSmx205022 		dev_param_p->jumbo = B_FALSE;
4866f3e57acSmx205022 		dev_param_p->tx_rx_64byte = B_TRUE;
4876f3e57acSmx205022 		dev_param_p->rx_hw_checksum = B_FALSE;
4886f3e57acSmx205022 		dev_param_p->tx_hw_checksum = 0;
4896f3e57acSmx205022 		dev_param_p->desc_type = DESC_OFFLOAD;
4906f3e57acSmx205022 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
4916f3e57acSmx205022 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
4926f3e57acSmx205022 		dev_param_p->nge_split = NGE_SPLIT_32;
4936f3e57acSmx205022 		break;
4946f3e57acSmx205022 
4956f3e57acSmx205022 	case DEVICE_ID_MCP55_372:
4966f3e57acSmx205022 	case DEVICE_ID_MCP55_373:
4976f3e57acSmx205022 		dev_param_p->msi = B_TRUE;
4986f3e57acSmx205022 		dev_param_p->msi_x = B_TRUE;
4996f3e57acSmx205022 		dev_param_p->vlan = B_TRUE;
5009ae6bcf1Sjj146644 		dev_param_p->advanced_pm = B_TRUE;
501d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->mac_addr_order = B_FALSE;
5026f3e57acSmx205022 		dev_param_p->tx_pause_frame = B_TRUE;
5036f3e57acSmx205022 		dev_param_p->rx_pause_frame = B_TRUE;
5046f3e57acSmx205022 		dev_param_p->jumbo = B_TRUE;
5056f3e57acSmx205022 		dev_param_p->tx_rx_64byte = B_TRUE;
5066f3e57acSmx205022 		dev_param_p->rx_hw_checksum = B_TRUE;
5076f3e57acSmx205022 		dev_param_p->tx_hw_checksum = HCKSUM_IPHDRCKSUM;
5086f3e57acSmx205022 		dev_param_p->desc_type = DESC_HOT;
5096f3e57acSmx205022 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_3072;
5106f3e57acSmx205022 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_3072;
5116f3e57acSmx205022 		dev_param_p->nge_split = NGE_SPLIT_96;
5126f3e57acSmx205022 		break;
5136f3e57acSmx205022 
514d27d4a13SMiles Xu, Sun Microsystems 	case DEVICE_ID_MCP61_3EE:
515d27d4a13SMiles Xu, Sun Microsystems 	case DEVICE_ID_MCP61_3EF:
516d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->msi = B_FALSE;
517d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->msi_x = B_FALSE;
518d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->vlan = B_FALSE;
519d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->advanced_pm = B_TRUE;
520d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->mac_addr_order = B_TRUE;
521d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->tx_pause_frame = B_FALSE;
522d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->rx_pause_frame = B_FALSE;
523d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->jumbo = B_FALSE;
524d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->tx_rx_64byte = B_TRUE;
525d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->rx_hw_checksum = B_FALSE;
526d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->tx_hw_checksum = 0;
527d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->desc_type = DESC_OFFLOAD;
528d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
529d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
530d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->nge_split = NGE_SPLIT_32;
531d27d4a13SMiles Xu, Sun Microsystems 		break;
532d27d4a13SMiles Xu, Sun Microsystems 
533a01a4735SWinson Wang - Sun Microsystems - Beijing China 	case DEVICE_ID_MCP77_760:
5349fa05d92SWinson Wang - Sun Microsystems - Beijing China 	case DEVICE_ID_MCP79_AB0:
535a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->msi = B_FALSE;
536a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->msi_x = B_FALSE;
537a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->vlan = B_FALSE;
538a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->advanced_pm = B_TRUE;
539a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->mac_addr_order = B_TRUE;
540a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->tx_pause_frame = B_FALSE;
541a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->rx_pause_frame = B_FALSE;
542a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->jumbo = B_FALSE;
543a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->tx_rx_64byte = B_TRUE;
544a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->rx_hw_checksum = B_FALSE;
545a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->tx_hw_checksum = 0;
546a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->desc_type = DESC_HOT;
547a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
548a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
549a01a4735SWinson Wang - Sun Microsystems - Beijing China 		dev_param_p->nge_split = NGE_SPLIT_32;
550a01a4735SWinson Wang - Sun Microsystems - Beijing China 		break;
551a01a4735SWinson Wang - Sun Microsystems - Beijing China 
5526f3e57acSmx205022 	default:
5536f3e57acSmx205022 		dev_param_p->msi = B_FALSE;
5546f3e57acSmx205022 		dev_param_p->msi_x = B_FALSE;
5556f3e57acSmx205022 		dev_param_p->vlan = B_FALSE;
5569ae6bcf1Sjj146644 		dev_param_p->advanced_pm = B_FALSE;
557d27d4a13SMiles Xu, Sun Microsystems 		dev_param_p->mac_addr_order = B_FALSE;
5586f3e57acSmx205022 		dev_param_p->tx_pause_frame = B_FALSE;
5596f3e57acSmx205022 		dev_param_p->rx_pause_frame = B_FALSE;
5606f3e57acSmx205022 		dev_param_p->jumbo = B_FALSE;
5616f3e57acSmx205022 		dev_param_p->tx_rx_64byte = B_FALSE;
5626f3e57acSmx205022 		dev_param_p->rx_hw_checksum = B_FALSE;
5636f3e57acSmx205022 		dev_param_p->tx_hw_checksum = 0;
5646f3e57acSmx205022 		dev_param_p->desc_type = DESC_OFFLOAD;
5656f3e57acSmx205022 		dev_param_p->rx_desc_num = NGE_RECV_SLOTS_DESC_1024;
5666f3e57acSmx205022 		dev_param_p->tx_desc_num = NGE_SEND_SLOTS_DESC_1024;
5676f3e57acSmx205022 		dev_param_p->nge_split = NGE_SPLIT_32;
5686f3e57acSmx205022 		return;
5696f3e57acSmx205022 	}
5706f3e57acSmx205022 }
5716f3e57acSmx205022 /*
5726f3e57acSmx205022  * Perform first-stage chip (re-)initialisation, using only config-space
5736f3e57acSmx205022  * accesses:
5746f3e57acSmx205022  *
5756f3e57acSmx205022  * + Read the vendor/device/revision/subsystem/cache-line-size registers,
5766f3e57acSmx205022  *   returning the data in the structure pointed to by <infop>.
5776f3e57acSmx205022  */
5786f3e57acSmx205022 void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset);
5796f3e57acSmx205022 #pragma	no_inline(nge_chip_cfg_init)
5806f3e57acSmx205022 
5816f3e57acSmx205022 void
nge_chip_cfg_init(nge_t * ngep,chip_info_t * infop,boolean_t reset)5826f3e57acSmx205022 nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset)
5836f3e57acSmx205022 {
5846f3e57acSmx205022 	uint16_t command;
5856f3e57acSmx205022 	ddi_acc_handle_t handle;
5866f3e57acSmx205022 	nge_interbus_conf interbus_conf;
5876f3e57acSmx205022 	nge_msi_mask_conf msi_mask_conf;
5886f3e57acSmx205022 	nge_msi_map_cap_conf cap_conf;
5896f3e57acSmx205022 
5906f3e57acSmx205022 	NGE_TRACE(("nge_chip_cfg_init($%p, $%p, %d)",
5916f3e57acSmx205022 	    (void *)ngep, (void *)infop, reset));
5926f3e57acSmx205022 
5936f3e57acSmx205022 	/*
5946f3e57acSmx205022 	 * save PCI cache line size and subsystem vendor ID
5956f3e57acSmx205022 	 *
5966f3e57acSmx205022 	 * Read all the config-space registers that characterise the
5976f3e57acSmx205022 	 * chip, specifically vendor/device/revision/subsystem vendor
5986f3e57acSmx205022 	 * and subsystem device id.  We expect (but don't check) that
5996f3e57acSmx205022 	 */
6006f3e57acSmx205022 	handle = ngep->cfg_handle;
6016f3e57acSmx205022 	/* reading the vendor information once */
6026f3e57acSmx205022 	if (reset == B_FALSE) {
6036f3e57acSmx205022 		infop->command = pci_config_get16(handle,
6046f3e57acSmx205022 		    PCI_CONF_COMM);
6056f3e57acSmx205022 		infop->vendor = pci_config_get16(handle,
6066f3e57acSmx205022 		    PCI_CONF_VENID);
6076f3e57acSmx205022 		infop->device = pci_config_get16(handle,
6086f3e57acSmx205022 		    PCI_CONF_DEVID);
6096f3e57acSmx205022 		infop->subven = pci_config_get16(handle,
6106f3e57acSmx205022 		    PCI_CONF_SUBVENID);
6116f3e57acSmx205022 		infop->subdev = pci_config_get16(handle,
6126f3e57acSmx205022 		    PCI_CONF_SUBSYSID);
6136f3e57acSmx205022 		infop->class_code = pci_config_get8(handle,
6146f3e57acSmx205022 		    PCI_CONF_BASCLASS);
6156f3e57acSmx205022 		infop->revision = pci_config_get8(handle,
6166f3e57acSmx205022 		    PCI_CONF_REVID);
6176f3e57acSmx205022 		infop->clsize = pci_config_get8(handle,
6186f3e57acSmx205022 		    PCI_CONF_CACHE_LINESZ);
6196f3e57acSmx205022 		infop->latency = pci_config_get8(handle,
6206f3e57acSmx205022 		    PCI_CONF_LATENCY_TIMER);
6216f3e57acSmx205022 	}
6226f3e57acSmx205022 	if (nge_enable_msi) {
6236f3e57acSmx205022 		/* Disable the hidden for MSI support */
6246f3e57acSmx205022 		interbus_conf.conf_val = pci_config_get32(handle,
6256f3e57acSmx205022 		    PCI_CONF_HT_INTERNAL);
6266f3e57acSmx205022 		if ((infop->device == DEVICE_ID_MCP55_373) ||
6276f3e57acSmx205022 		    (infop->device == DEVICE_ID_MCP55_372))
6286f3e57acSmx205022 			interbus_conf.conf_bits.msix_off = NGE_SET;
6296f3e57acSmx205022 		interbus_conf.conf_bits.msi_off = NGE_CLEAR;
6306f3e57acSmx205022 		pci_config_put32(handle, PCI_CONF_HT_INTERNAL,
6316f3e57acSmx205022 		    interbus_conf.conf_val);
6326f3e57acSmx205022 
6336f3e57acSmx205022 		if ((infop->device == DEVICE_ID_MCP55_373) ||
6346f3e57acSmx205022 		    (infop->device == DEVICE_ID_MCP55_372)) {
6356f3e57acSmx205022 
6366f3e57acSmx205022 			/* Disable the vector off for mcp55 */
6376f3e57acSmx205022 			msi_mask_conf.msi_mask_conf_val =
6386f3e57acSmx205022 			    pci_config_get32(handle, PCI_CONF_HT_MSI_MASK);
6396f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec0_off = NGE_CLEAR;
6406f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec1_off = NGE_CLEAR;
6416f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec2_off = NGE_CLEAR;
6426f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec3_off = NGE_CLEAR;
6436f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec4_off = NGE_CLEAR;
6446f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec5_off = NGE_CLEAR;
6456f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec6_off = NGE_CLEAR;
6466f3e57acSmx205022 			msi_mask_conf.msi_mask_bits.vec7_off = NGE_CLEAR;
6476f3e57acSmx205022 			pci_config_put32(handle, PCI_CONF_HT_MSI_MASK,
6486f3e57acSmx205022 			    msi_mask_conf.msi_mask_conf_val);
6496f3e57acSmx205022 
6506f3e57acSmx205022 			/* Enable the MSI mapping */
6516f3e57acSmx205022 			cap_conf.msi_map_cap_conf_val =
6526f3e57acSmx205022 			    pci_config_get32(handle, PCI_CONF_HT_MSI_MAP_CAP);
6536f3e57acSmx205022 			cap_conf.map_cap_conf_bits.map_en = NGE_SET;
6546f3e57acSmx205022 			pci_config_put32(handle, PCI_CONF_HT_MSI_MAP_CAP,
6556f3e57acSmx205022 			    cap_conf.msi_map_cap_conf_val);
6566f3e57acSmx205022 		}
6576f3e57acSmx205022 	} else {
6586f3e57acSmx205022 		interbus_conf.conf_val = pci_config_get32(handle,
6596f3e57acSmx205022 		    PCI_CONF_HT_INTERNAL);
6606f3e57acSmx205022 		interbus_conf.conf_bits.msi_off = NGE_SET;
6616f3e57acSmx205022 		pci_config_put32(handle, PCI_CONF_HT_INTERNAL,
6626f3e57acSmx205022 		    interbus_conf.conf_val);
6636f3e57acSmx205022 	}
6646f3e57acSmx205022 	command = infop->command | PCI_COMM_MAE;
6656f3e57acSmx205022 	command &= ~PCI_COMM_MEMWR_INVAL;
6666f3e57acSmx205022 	command |= PCI_COMM_ME;
6676f3e57acSmx205022 	pci_config_put16(handle, PCI_CONF_COMM, command);
6686f3e57acSmx205022 	pci_config_put16(handle, PCI_CONF_STAT, ~0);
6696f3e57acSmx205022 
6706f3e57acSmx205022 }
6716f3e57acSmx205022 
6726f3e57acSmx205022 int
nge_chip_stop(nge_t * ngep,boolean_t fault)6736f3e57acSmx205022 nge_chip_stop(nge_t *ngep, boolean_t fault)
6746f3e57acSmx205022 {
6756f3e57acSmx205022 	int err;
6766f3e57acSmx205022 	uint32_t reg_val;
6776f3e57acSmx205022 	uint32_t	tries;
6786f3e57acSmx205022 	nge_mintr_src mintr_src;
6796f3e57acSmx205022 	nge_mii_cs mii_cs;
6806f3e57acSmx205022 	nge_rx_poll rx_poll;
6816f3e57acSmx205022 	nge_tx_poll tx_poll;
6826f3e57acSmx205022 	nge_rx_en rx_en;
6836f3e57acSmx205022 	nge_tx_en tx_en;
6846f3e57acSmx205022 	nge_tx_sta tx_sta;
6856f3e57acSmx205022 	nge_rx_sta rx_sta;
6866f3e57acSmx205022 	nge_mode_cntl mode;
6876f3e57acSmx205022 	nge_pmu_cntl2 pmu_cntl2;
6886f3e57acSmx205022 
6896f3e57acSmx205022 	NGE_TRACE(("nge_chip_stop($%p, %d)", (void *)ngep, fault));
6906f3e57acSmx205022 
6916f3e57acSmx205022 	err = DDI_SUCCESS;
6929ae6bcf1Sjj146644 
6939ae6bcf1Sjj146644 	/* Clear any pending PHY interrupt */
6946f3e57acSmx205022 	mintr_src.src_val = nge_reg_get8(ngep, NGE_MINTR_SRC);
6956f3e57acSmx205022 	nge_reg_put8(ngep, NGE_MINTR_SRC, mintr_src.src_val);
6966f3e57acSmx205022 
6976f3e57acSmx205022 	/* Mask all interrupts */
6986f3e57acSmx205022 	reg_val = nge_reg_get32(ngep, NGE_INTR_MASK);
6996f3e57acSmx205022 	reg_val &= ~NGE_INTR_ALL_EN;
7006f3e57acSmx205022 	nge_reg_put32(ngep, NGE_INTR_MASK, reg_val);
7016f3e57acSmx205022 
7026f3e57acSmx205022 	/* Disable auto-polling of phy */
7036f3e57acSmx205022 	mii_cs.cs_val = nge_reg_get32(ngep, NGE_MII_CS);
7046f3e57acSmx205022 	mii_cs.cs_bits.ap_en = NGE_CLEAR;
7056f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MII_CS, mii_cs.cs_val);
7066f3e57acSmx205022 
7076f3e57acSmx205022 	/* Reset buffer management & DMA */
7086f3e57acSmx205022 	mode.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
7096f3e57acSmx205022 	mode.mode_bits.dma_dis = NGE_SET;
7106f3e57acSmx205022 	mode.mode_bits.desc_type = ngep->desc_mode;
7116f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MODE_CNTL, mode.mode_val);
7126f3e57acSmx205022 
7136de4f663Smx205022 	for (tries = 0; tries < 10000; tries++) {
7146f3e57acSmx205022 		drv_usecwait(10);
7156f3e57acSmx205022 		mode.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
7166f3e57acSmx205022 		if (mode.mode_bits.dma_status == NGE_SET)
7176f3e57acSmx205022 			break;
7186f3e57acSmx205022 	}
7196de4f663Smx205022 	if (tries == 10000) {
720a01a4735SWinson Wang - Sun Microsystems - Beijing China 		ngep->nge_chip_state = NGE_CHIP_ERROR;
7216f3e57acSmx205022 		return (DDI_FAILURE);
7226f3e57acSmx205022 	}
7236f3e57acSmx205022 
7246f3e57acSmx205022 	/* Disable rx's machine */
7256f3e57acSmx205022 	rx_en.val = nge_reg_get8(ngep, NGE_RX_EN);
7266f3e57acSmx205022 	rx_en.bits.rx_en = NGE_CLEAR;
7276f3e57acSmx205022 	nge_reg_put8(ngep, NGE_RX_EN, rx_en.val);
7286f3e57acSmx205022 
7296f3e57acSmx205022 	/* Disable tx's machine */
7306f3e57acSmx205022 	tx_en.val = nge_reg_get8(ngep, NGE_TX_EN);
7316f3e57acSmx205022 	tx_en.bits.tx_en = NGE_CLEAR;
7326f3e57acSmx205022 	nge_reg_put8(ngep, NGE_TX_EN, tx_en.val);
7336f3e57acSmx205022 
7346f3e57acSmx205022 	/*
7356f3e57acSmx205022 	 * Clean the status of tx's state machine
7366f3e57acSmx205022 	 * and Make assure the tx's channel is idle
7376f3e57acSmx205022 	 */
7386f3e57acSmx205022 	tx_sta.sta_val = nge_reg_get32(ngep, NGE_TX_STA);
7396f3e57acSmx205022 	for (tries = 0; tries < 1000; tries++) {
7406f3e57acSmx205022 		if (tx_sta.sta_bits.tx_chan_sta == NGE_CLEAR)
7416f3e57acSmx205022 			break;
7426f3e57acSmx205022 		drv_usecwait(10);
7436f3e57acSmx205022 		tx_sta.sta_val = nge_reg_get32(ngep, NGE_TX_STA);
7446f3e57acSmx205022 	}
7456f3e57acSmx205022 	if (tries == 1000) {
746a01a4735SWinson Wang - Sun Microsystems - Beijing China 		ngep->nge_chip_state = NGE_CHIP_ERROR;
7476f3e57acSmx205022 		return (DDI_FAILURE);
7486f3e57acSmx205022 	}
7496f3e57acSmx205022 	nge_reg_put32(ngep, NGE_TX_STA,  tx_sta.sta_val);
7506f3e57acSmx205022 
7516f3e57acSmx205022 	/*
7526f3e57acSmx205022 	 * Clean the status of rx's state machine
7536f3e57acSmx205022 	 * and Make assure the tx's channel is idle
7546f3e57acSmx205022 	 */
7556f3e57acSmx205022 	rx_sta.sta_val = nge_reg_get32(ngep, NGE_RX_STA);
7566f3e57acSmx205022 	for (tries = 0; tries < 1000; tries++) {
7576f3e57acSmx205022 		if (rx_sta.sta_bits.rx_chan_sta == NGE_CLEAR)
7586f3e57acSmx205022 			break;
7596f3e57acSmx205022 		drv_usecwait(10);
7606f3e57acSmx205022 		rx_sta.sta_val = nge_reg_get32(ngep, NGE_RX_STA);
7616f3e57acSmx205022 	}
7626f3e57acSmx205022 	if (tries == 1000) {
763a01a4735SWinson Wang - Sun Microsystems - Beijing China 		ngep->nge_chip_state = NGE_CHIP_ERROR;
7646f3e57acSmx205022 		return (DDI_FAILURE);
7656f3e57acSmx205022 	}
7666f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_STA, rx_sta.sta_val);
7676f3e57acSmx205022 
7689ae6bcf1Sjj146644 	/* Disable auto-poll of rx's state machine */
7699ae6bcf1Sjj146644 	rx_poll.poll_val = nge_reg_get32(ngep, NGE_RX_POLL);
7709ae6bcf1Sjj146644 	rx_poll.poll_bits.rpen = NGE_CLEAR;
7719ae6bcf1Sjj146644 	rx_poll.poll_bits.rpi = NGE_CLEAR;
7729ae6bcf1Sjj146644 	nge_reg_put32(ngep, NGE_RX_POLL, rx_poll.poll_val);
7739ae6bcf1Sjj146644 
7749ae6bcf1Sjj146644 	/* Disable auto-polling of tx's  state machine */
7759ae6bcf1Sjj146644 	tx_poll.poll_val = nge_reg_get32(ngep, NGE_TX_POLL);
7769ae6bcf1Sjj146644 	tx_poll.poll_bits.tpen = NGE_CLEAR;
7779ae6bcf1Sjj146644 	tx_poll.poll_bits.tpi = NGE_CLEAR;
7789ae6bcf1Sjj146644 	nge_reg_put32(ngep, NGE_TX_POLL, tx_poll.poll_val);
7799ae6bcf1Sjj146644 
7809ae6bcf1Sjj146644 	/* Restore buffer management */
7819ae6bcf1Sjj146644 	mode.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
7829ae6bcf1Sjj146644 	mode.mode_bits.bm_reset = NGE_SET;
7839ae6bcf1Sjj146644 	mode.mode_bits.tx_rcom_en = NGE_SET;
7849ae6bcf1Sjj146644 	nge_reg_put32(ngep, NGE_MODE_CNTL, mode.mode_val);
7859ae6bcf1Sjj146644 
7869ae6bcf1Sjj146644 	if (ngep->dev_spec_param.advanced_pm) {
7876f3e57acSmx205022 
7886f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_CIDLE_LIMIT, 0);
7896f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_DIDLE_LIMIT, 0);
7906f3e57acSmx205022 
7916f3e57acSmx205022 		pmu_cntl2.cntl2_val = nge_reg_get32(ngep, NGE_PMU_CNTL2);
7926f3e57acSmx205022 		pmu_cntl2.cntl2_bits.cidle_timer = NGE_CLEAR;
7936f3e57acSmx205022 		pmu_cntl2.cntl2_bits.didle_timer = NGE_CLEAR;
7946f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_CNTL2, pmu_cntl2.cntl2_val);
7956f3e57acSmx205022 	}
7966f3e57acSmx205022 	if (fault)
7976f3e57acSmx205022 		ngep->nge_chip_state = NGE_CHIP_FAULT;
7986f3e57acSmx205022 	else
7996f3e57acSmx205022 		ngep->nge_chip_state = NGE_CHIP_STOPPED;
8006f3e57acSmx205022 
8016f3e57acSmx205022 	return (err);
8026f3e57acSmx205022 }
8036f3e57acSmx205022 
8046f3e57acSmx205022 static void
nge_rx_setup(nge_t * ngep)8056f3e57acSmx205022 nge_rx_setup(nge_t *ngep)
8066f3e57acSmx205022 {
8076f3e57acSmx205022 	uint64_t desc_addr;
8086f3e57acSmx205022 	nge_rxtx_dlen dlen;
8096f3e57acSmx205022 	nge_rx_poll rx_poll;
8106f3e57acSmx205022 
8116f3e57acSmx205022 	/*
8126f3e57acSmx205022 	 * Filling the address and length of rx's descriptors
8136f3e57acSmx205022 	 */
8146f3e57acSmx205022 	desc_addr = ngep->recv->desc.cookie.dmac_laddress;
8156f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_DADR, desc_addr);
8166f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_DADR_HI, desc_addr >> 32);
8176f3e57acSmx205022 	dlen.dlen_val = nge_reg_get32(ngep, NGE_RXTX_DLEN);
8186f3e57acSmx205022 	dlen.dlen_bits.rdlen = ngep->recv->desc.nslots - 1;
8196f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RXTX_DLEN, dlen.dlen_val);
8206f3e57acSmx205022 
8216f3e57acSmx205022 	rx_poll.poll_val = nge_reg_get32(ngep, NGE_RX_POLL);
8226f3e57acSmx205022 	rx_poll.poll_bits.rpi = RX_POLL_INTV_1G;
8236f3e57acSmx205022 	rx_poll.poll_bits.rpen = NGE_SET;
8246f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_POLL, rx_poll.poll_val);
8256f3e57acSmx205022 }
8266f3e57acSmx205022 
8276f3e57acSmx205022 static void
nge_tx_setup(nge_t * ngep)8286f3e57acSmx205022 nge_tx_setup(nge_t *ngep)
8296f3e57acSmx205022 {
8306f3e57acSmx205022 	uint64_t desc_addr;
8316f3e57acSmx205022 	nge_rxtx_dlen dlen;
8326f3e57acSmx205022 
8336f3e57acSmx205022 	/*
8346f3e57acSmx205022 	 * Filling the address and length of tx's descriptors
8356f3e57acSmx205022 	 */
8366f3e57acSmx205022 	desc_addr = ngep->send->desc.cookie.dmac_laddress;
8376f3e57acSmx205022 	nge_reg_put32(ngep, NGE_TX_DADR, desc_addr);
8386f3e57acSmx205022 	nge_reg_put32(ngep, NGE_TX_DADR_HI, desc_addr >> 32);
8396f3e57acSmx205022 	dlen.dlen_val = nge_reg_get32(ngep, NGE_RXTX_DLEN);
8406f3e57acSmx205022 	dlen.dlen_bits.tdlen = ngep->send->desc.nslots - 1;
8416f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RXTX_DLEN, dlen.dlen_val);
8426f3e57acSmx205022 }
8436f3e57acSmx205022 
8446f3e57acSmx205022 static int
nge_buff_setup(nge_t * ngep)8456f3e57acSmx205022 nge_buff_setup(nge_t *ngep)
8466f3e57acSmx205022 {
8476f3e57acSmx205022 	nge_mode_cntl mode_cntl;
8486f3e57acSmx205022 	nge_dev_spec_param_t	*dev_param_p;
8496f3e57acSmx205022 
8506f3e57acSmx205022 	dev_param_p = &ngep->dev_spec_param;
8516f3e57acSmx205022 
8526f3e57acSmx205022 	/*
8536f3e57acSmx205022 	 * Configure Rx&Tx's buffer
8546f3e57acSmx205022 	 */
8556f3e57acSmx205022 	nge_rx_setup(ngep);
8566f3e57acSmx205022 	nge_tx_setup(ngep);
8576f3e57acSmx205022 
8586f3e57acSmx205022 	/*
8596f3e57acSmx205022 	 * Configure buffer attribute
8606f3e57acSmx205022 	 */
8616f3e57acSmx205022 	mode_cntl.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
8626f3e57acSmx205022 
8636f3e57acSmx205022 	/*
8646f3e57acSmx205022 	 * Enable Dma access request
8656f3e57acSmx205022 	 */
8666f3e57acSmx205022 	mode_cntl.mode_bits.dma_dis = NGE_CLEAR;
8676f3e57acSmx205022 
8686f3e57acSmx205022 	/*
8696f3e57acSmx205022 	 * Enbale Buffer management
8706f3e57acSmx205022 	 */
8716f3e57acSmx205022 	mode_cntl.mode_bits.bm_reset = NGE_CLEAR;
8726f3e57acSmx205022 
8736f3e57acSmx205022 	/*
8746f3e57acSmx205022 	 * Support Standoffload Descriptor
8756f3e57acSmx205022 	 */
8766f3e57acSmx205022 	mode_cntl.mode_bits.desc_type = ngep->desc_mode;
8776f3e57acSmx205022 
8786f3e57acSmx205022 	/*
8796f3e57acSmx205022 	 * Support receive hardware checksum
8806f3e57acSmx205022 	 */
8816f3e57acSmx205022 	if (dev_param_p->rx_hw_checksum) {
8826f3e57acSmx205022 		mode_cntl.mode_bits.rx_sum_en = NGE_SET;
8836f3e57acSmx205022 	} else
8846f3e57acSmx205022 		mode_cntl.mode_bits.rx_sum_en = NGE_CLEAR;
8856f3e57acSmx205022 
8866f3e57acSmx205022 	/*
8876f3e57acSmx205022 	 * Disable Tx PRD coarse update
8886f3e57acSmx205022 	 */
8896f3e57acSmx205022 	mode_cntl.mode_bits.tx_prd_cu_en = NGE_CLEAR;
8906f3e57acSmx205022 
8916f3e57acSmx205022 	/*
8926f3e57acSmx205022 	 * Disable 64-byte access
8936f3e57acSmx205022 	 */
8946f3e57acSmx205022 	mode_cntl.mode_bits.w64_dis = NGE_SET;
8956f3e57acSmx205022 
8966f3e57acSmx205022 	/*
8976f3e57acSmx205022 	 * Skip Rx Error Frame is not supported and if
8986f3e57acSmx205022 	 * enable it, jumbo frame does not work any more.
8996f3e57acSmx205022 	 */
9006f3e57acSmx205022 	mode_cntl.mode_bits.rx_filter_en = NGE_CLEAR;
9016f3e57acSmx205022 
9026f3e57acSmx205022 	/*
9036f3e57acSmx205022 	 * Can not support hot mode now
9046f3e57acSmx205022 	 */
9056f3e57acSmx205022 	mode_cntl.mode_bits.resv15 = NGE_CLEAR;
9066f3e57acSmx205022 
9076f3e57acSmx205022 	if (dev_param_p->vlan) {
9086f3e57acSmx205022 		/* Disable the vlan strip for devices which support vlan */
9096f3e57acSmx205022 		mode_cntl.mode_bits.vlan_strip = NGE_CLEAR;
9106f3e57acSmx205022 
9116f3e57acSmx205022 		/* Disable the vlan insert for devices which supprot vlan */
9126f3e57acSmx205022 		mode_cntl.mode_bits.vlan_ins = NGE_CLEAR;
9136f3e57acSmx205022 	}
9146f3e57acSmx205022 
9156f3e57acSmx205022 	if (dev_param_p->tx_rx_64byte) {
9166f3e57acSmx205022 
9176f3e57acSmx205022 		/* Set the maximum TX PRD fetch size to 64 bytes */
9186f3e57acSmx205022 		mode_cntl.mode_bits.tx_fetch_prd = NGE_SET;
9196f3e57acSmx205022 
9206f3e57acSmx205022 		/* Set the maximum RX PRD fetch size to 64 bytes */
9216f3e57acSmx205022 		mode_cntl.mode_bits.rx_fetch_prd = NGE_SET;
9226f3e57acSmx205022 	}
9236f3e57acSmx205022 	/*
9246f3e57acSmx205022 	 * Upload Rx data as it arrives, rather than waiting for full frame
9256f3e57acSmx205022 	 */
9266f3e57acSmx205022 	mode_cntl.mode_bits.resv16 = NGE_CLEAR;
9276f3e57acSmx205022 
9286f3e57acSmx205022 	/*
9296f3e57acSmx205022 	 * Normal HOT table accesses
9306f3e57acSmx205022 	 */
9316f3e57acSmx205022 	mode_cntl.mode_bits.resv17 = NGE_CLEAR;
9326f3e57acSmx205022 
9336f3e57acSmx205022 	/*
9346f3e57acSmx205022 	 * Normal HOT buffer requesting
9356f3e57acSmx205022 	 */
9366f3e57acSmx205022 	mode_cntl.mode_bits.resv18 = NGE_CLEAR;
9376f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MODE_CNTL, mode_cntl.mode_val);
9386f3e57acSmx205022 
9396f3e57acSmx205022 	/*
9406f3e57acSmx205022 	 * Signal controller to check for new Rx descriptors
9416f3e57acSmx205022 	 */
9426f3e57acSmx205022 	mode_cntl.mode_val = nge_reg_get32(ngep, NGE_MODE_CNTL);
9436f3e57acSmx205022 	mode_cntl.mode_bits.rxdm = NGE_SET;
9446f3e57acSmx205022 	mode_cntl.mode_bits.tx_rcom_en = NGE_SET;
9456f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MODE_CNTL, mode_cntl.mode_val);
9466f3e57acSmx205022 
9476f3e57acSmx205022 
9486f3e57acSmx205022 	return (DDI_SUCCESS);
9496f3e57acSmx205022 }
9506f3e57acSmx205022 
9516f3e57acSmx205022 /*
9526f3e57acSmx205022  * When chipset resets, the chipset can not restore  the orignial
9536f3e57acSmx205022  * mac address to the mac address registers.
9546f3e57acSmx205022  *
9556f3e57acSmx205022  * When the driver is dettached, the function will write the orignial
9566f3e57acSmx205022  * mac address to the mac address registers.
9576f3e57acSmx205022  */
9586f3e57acSmx205022 
9596f3e57acSmx205022 void
nge_restore_mac_addr(nge_t * ngep)9606f3e57acSmx205022 nge_restore_mac_addr(nge_t *ngep)
9616f3e57acSmx205022 {
9626f3e57acSmx205022 	uint32_t mac_addr;
9636f3e57acSmx205022 
9646f3e57acSmx205022 	mac_addr = (uint32_t)ngep->chipinfo.hw_mac_addr;
9656f3e57acSmx205022 	nge_reg_put32(ngep, NGE_UNI_ADDR0, mac_addr);
9666f3e57acSmx205022 	mac_addr = (uint32_t)(ngep->chipinfo.hw_mac_addr >> 32);
9676f3e57acSmx205022 	nge_reg_put32(ngep, NGE_UNI_ADDR1, mac_addr);
9686f3e57acSmx205022 }
9696f3e57acSmx205022 
9706f3e57acSmx205022 int
nge_chip_reset(nge_t * ngep)9716f3e57acSmx205022 nge_chip_reset(nge_t *ngep)
9726f3e57acSmx205022 {
9736f3e57acSmx205022 	int err;
9746f3e57acSmx205022 	uint8_t i;
9756f3e57acSmx205022 	uint32_t regno;
976d27d4a13SMiles Xu, Sun Microsystems 	uint64_t mac = 0;
9776f3e57acSmx205022 	nge_uni_addr1 uaddr1;
9786f3e57acSmx205022 	nge_cp_cntl ee_cntl;
9796f3e57acSmx205022 	nge_soft_misc soft_misc;
9806f3e57acSmx205022 	nge_pmu_cntl0 pmu_cntl0;
9816f3e57acSmx205022 	nge_pmu_cntl2 pmu_cntl2;
9826f3e57acSmx205022 	nge_pm_cntl2 pm_cntl2;
9836f3e57acSmx205022 	const nge_ksindex_t *ksip;
9846f3e57acSmx205022 
9856f3e57acSmx205022 	NGE_TRACE(("nge_chip_reset($%p)", (void *)ngep));
9866f3e57acSmx205022 
9876f3e57acSmx205022 	/*
9886f3e57acSmx205022 	 * Clear the statistics by reading the statistics register
9896f3e57acSmx205022 	 */
9906f3e57acSmx205022 	for (ksip = nge_statistics; ksip->name != NULL; ++ksip) {
9916f3e57acSmx205022 		regno = KS_BASE + ksip->index * sizeof (uint32_t);
9926f3e57acSmx205022 		(void) nge_reg_get32(ngep, regno);
9936f3e57acSmx205022 	}
9946f3e57acSmx205022 
9956f3e57acSmx205022 	/*
9966f3e57acSmx205022 	 * Setup seeprom control
9976f3e57acSmx205022 	 */
9986f3e57acSmx205022 	ee_cntl.cntl_val = nge_reg_get32(ngep, NGE_EP_CNTL);
9996f3e57acSmx205022 	ee_cntl.cntl_bits.clkdiv = EEPROM_CLKDIV;
10006f3e57acSmx205022 	ee_cntl.cntl_bits.rom_size = EEPROM_32K;
10016f3e57acSmx205022 	ee_cntl.cntl_bits.word_wid = ACCESS_16BIT;
10026f3e57acSmx205022 	ee_cntl.cntl_bits.wait_slots = EEPROM_WAITCLK;
10036f3e57acSmx205022 	nge_reg_put32(ngep, NGE_EP_CNTL, ee_cntl.cntl_val);
10046f3e57acSmx205022 
10056f3e57acSmx205022 	/*
10066f3e57acSmx205022 	 * Reading the unicast mac address table
10076f3e57acSmx205022 	 */
10086f3e57acSmx205022 	if (ngep->nge_chip_state == NGE_CHIP_INITIAL) {
10096f3e57acSmx205022 		uaddr1.addr_val = nge_reg_get32(ngep, NGE_UNI_ADDR1);
10106f3e57acSmx205022 		mac = uaddr1.addr_bits.addr;
10116f3e57acSmx205022 		mac <<= 32;
10126f3e57acSmx205022 		mac |= nge_reg_get32(ngep, NGE_UNI_ADDR0);
1013a01a4735SWinson Wang - Sun Microsystems - Beijing China 			ngep->chipinfo.hw_mac_addr = mac;
1014a01a4735SWinson Wang - Sun Microsystems - Beijing China 			if (ngep->dev_spec_param.mac_addr_order) {
1015d27d4a13SMiles Xu, Sun Microsystems 				for (i = 0; i < ETHERADDRL; i++) {
1016a01a4735SWinson Wang - Sun Microsystems - Beijing China 					ngep->chipinfo.vendor_addr.addr[i] =
1017a01a4735SWinson Wang - Sun Microsystems - Beijing China 					    (uchar_t)mac;
1018a01a4735SWinson Wang - Sun Microsystems - Beijing China 					ngep->cur_uni_addr.addr[i] =
1019a01a4735SWinson Wang - Sun Microsystems - Beijing China 					    (uchar_t)mac;
1020d27d4a13SMiles Xu, Sun Microsystems 					mac >>= 8;
1021d27d4a13SMiles Xu, Sun Microsystems 				}
1022a01a4735SWinson Wang - Sun Microsystems - Beijing China 			} else {
10236f3e57acSmx205022 				for (i = ETHERADDRL; i-- != 0; ) {
10246f3e57acSmx205022 					ngep->chipinfo.vendor_addr.addr[i] =
10256f3e57acSmx205022 					    (uchar_t)mac;
1026a01a4735SWinson Wang - Sun Microsystems - Beijing China 					ngep->cur_uni_addr.addr[i] =
1027a01a4735SWinson Wang - Sun Microsystems - Beijing China 					    (uchar_t)mac;
10286f3e57acSmx205022 					mac >>= 8;
10296f3e57acSmx205022 				}
10306f3e57acSmx205022 			}
1031a01a4735SWinson Wang - Sun Microsystems - Beijing China 			ngep->chipinfo.vendor_addr.set = 1;
10326f3e57acSmx205022 	}
10336f3e57acSmx205022 	pci_config_put8(ngep->cfg_handle, PCI_CONF_CACHE_LINESZ,
10346f3e57acSmx205022 	    ngep->chipinfo.clsize);
10356f3e57acSmx205022 	pci_config_put8(ngep->cfg_handle, PCI_CONF_LATENCY_TIMER,
10366f3e57acSmx205022 	    ngep->chipinfo.latency);
10376f3e57acSmx205022 
10389ae6bcf1Sjj146644 
10399ae6bcf1Sjj146644 	if (ngep->dev_spec_param.advanced_pm) {
10406f3e57acSmx205022 
10416f3e57acSmx205022 		/* Program software misc register */
10426f3e57acSmx205022 		soft_misc.misc_val = nge_reg_get32(ngep, NGE_SOFT_MISC);
10436f3e57acSmx205022 		soft_misc.misc_bits.rx_clk_vx_rst = NGE_SET;
10446f3e57acSmx205022 		soft_misc.misc_bits.tx_clk_vx_rst = NGE_SET;
10456f3e57acSmx205022 		soft_misc.misc_bits.clk12m_vx_rst = NGE_SET;
10466f3e57acSmx205022 		soft_misc.misc_bits.fpci_clk_vx_rst = NGE_SET;
10476f3e57acSmx205022 		soft_misc.misc_bits.rx_clk_vc_rst = NGE_SET;
10486f3e57acSmx205022 		soft_misc.misc_bits.tx_clk_vc_rst = NGE_SET;
10496f3e57acSmx205022 		soft_misc.misc_bits.fs_clk_vc_rst = NGE_SET;
10506f3e57acSmx205022 		soft_misc.misc_bits.rst_ex_m2pintf = NGE_SET;
10516f3e57acSmx205022 		nge_reg_put32(ngep, NGE_SOFT_MISC, soft_misc.misc_val);
10526f3e57acSmx205022 
10539ae6bcf1Sjj146644 		/* wait for 32 us */
10549ae6bcf1Sjj146644 		drv_usecwait(32);
10556f3e57acSmx205022 
10566f3e57acSmx205022 		soft_misc.misc_val = nge_reg_get32(ngep, NGE_SOFT_MISC);
10576f3e57acSmx205022 		soft_misc.misc_bits.rx_clk_vx_rst = NGE_CLEAR;
10586f3e57acSmx205022 		soft_misc.misc_bits.tx_clk_vx_rst = NGE_CLEAR;
10596f3e57acSmx205022 		soft_misc.misc_bits.clk12m_vx_rst = NGE_CLEAR;
10606f3e57acSmx205022 		soft_misc.misc_bits.fpci_clk_vx_rst = NGE_CLEAR;
10616f3e57acSmx205022 		soft_misc.misc_bits.rx_clk_vc_rst = NGE_CLEAR;
10626f3e57acSmx205022 		soft_misc.misc_bits.tx_clk_vc_rst = NGE_CLEAR;
10636f3e57acSmx205022 		soft_misc.misc_bits.fs_clk_vc_rst = NGE_CLEAR;
10646f3e57acSmx205022 		soft_misc.misc_bits.rst_ex_m2pintf = NGE_CLEAR;
10656f3e57acSmx205022 		nge_reg_put32(ngep, NGE_SOFT_MISC, soft_misc.misc_val);
10666f3e57acSmx205022 
10676f3e57acSmx205022 		/* Program PMU registers */
10686f3e57acSmx205022 		pmu_cntl0.cntl0_val = nge_reg_get32(ngep, NGE_PMU_CNTL0);
10696f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd10_fp =
10706f3e57acSmx205022 		    NGE_PMU_CORE_SPD10_BUSY;
10716f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd10_idle =
10726f3e57acSmx205022 		    NGE_PMU_CORE_SPD10_IDLE;
10736f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd100_fp =
10746f3e57acSmx205022 		    NGE_PMU_CORE_SPD100_BUSY;
10756f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd100_idle =
10766f3e57acSmx205022 		    NGE_PMU_CORE_SPD100_IDLE;
10776f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd1000_fp =
10786f3e57acSmx205022 		    NGE_PMU_CORE_SPD1000_BUSY;
10796f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd1000_idle =
10806f3e57acSmx205022 		    NGE_PMU_CORE_SPD100_IDLE;
10816f3e57acSmx205022 		pmu_cntl0.cntl0_bits.core_spd10_idle =
10826f3e57acSmx205022 		    NGE_PMU_CORE_SPD10_IDLE;
10836f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_CNTL0, pmu_cntl0.cntl0_val);
10846f3e57acSmx205022 
10856f3e57acSmx205022 		/* Set the core idle limit value */
10866f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_CIDLE_LIMIT,
10876f3e57acSmx205022 		    NGE_PMU_CIDLE_LIMIT_DEF);
10886f3e57acSmx205022 
10896f3e57acSmx205022 		/* Set the device idle limit value */
10906f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_DIDLE_LIMIT,
10916f3e57acSmx205022 		    NGE_PMU_DIDLE_LIMIT_DEF);
10926f3e57acSmx205022 
10936f3e57acSmx205022 		/* Enable the core/device idle timer in PMU control 2 */
10946f3e57acSmx205022 		pmu_cntl2.cntl2_val = nge_reg_get32(ngep, NGE_PMU_CNTL2);
10956f3e57acSmx205022 		pmu_cntl2.cntl2_bits.cidle_timer = NGE_SET;
10966f3e57acSmx205022 		pmu_cntl2.cntl2_bits.didle_timer = NGE_SET;
10976f3e57acSmx205022 		pmu_cntl2.cntl2_bits.core_enable = NGE_SET;
10986f3e57acSmx205022 		pmu_cntl2.cntl2_bits.dev_enable = NGE_SET;
10996f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PMU_CNTL2, pmu_cntl2.cntl2_val);
11006f3e57acSmx205022 	}
11019ae6bcf1Sjj146644 	/*
11029ae6bcf1Sjj146644 	 * Stop the chipset and clear buffer management
11039ae6bcf1Sjj146644 	 */
11049ae6bcf1Sjj146644 	err = nge_chip_stop(ngep, B_FALSE);
11059ae6bcf1Sjj146644 	if (err == DDI_FAILURE)
11069ae6bcf1Sjj146644 		return (err);
11076f3e57acSmx205022 	/*
11086f3e57acSmx205022 	 * Clear the power state bits for phy since interface no longer
11096f3e57acSmx205022 	 * works after rebooting from Windows on a multi-boot machine
11106f3e57acSmx205022 	 */
11116f3e57acSmx205022 	if (ngep->chipinfo.device == DEVICE_ID_MCP51_268 ||
11126f3e57acSmx205022 	    ngep->chipinfo.device == DEVICE_ID_MCP51_269 ||
11136f3e57acSmx205022 	    ngep->chipinfo.device == DEVICE_ID_MCP55_372 ||
11146f3e57acSmx205022 	    ngep->chipinfo.device == DEVICE_ID_MCP55_373 ||
11156f3e57acSmx205022 	    ngep->chipinfo.device == DEVICE_ID_MCP61_3EE ||
1116a01a4735SWinson Wang - Sun Microsystems - Beijing China 	    ngep->chipinfo.device == DEVICE_ID_MCP61_3EF ||
11179fa05d92SWinson Wang - Sun Microsystems - Beijing China 	    ngep->chipinfo.device == DEVICE_ID_MCP77_760 ||
11189fa05d92SWinson Wang - Sun Microsystems - Beijing China 	    ngep->chipinfo.device == DEVICE_ID_MCP79_AB0) {
11196f3e57acSmx205022 
11206f3e57acSmx205022 		pm_cntl2.cntl_val = nge_reg_get32(ngep, NGE_PM_CNTL2);
11216f3e57acSmx205022 		/* bring phy out of coma mode */
11226f3e57acSmx205022 		pm_cntl2.cntl_bits.phy_coma_set = NGE_CLEAR;
11236f3e57acSmx205022 		/* disable auto reset coma bits */
11246f3e57acSmx205022 		pm_cntl2.cntl_bits.resv4 = NGE_CLEAR;
11256f3e57acSmx205022 		/* restore power to gated clocks */
11266f3e57acSmx205022 		pm_cntl2.cntl_bits.resv8_11 = NGE_CLEAR;
11276f3e57acSmx205022 		nge_reg_put32(ngep, NGE_PM_CNTL2, pm_cntl2.cntl_val);
11286f3e57acSmx205022 	}
11296f3e57acSmx205022 
11306f3e57acSmx205022 	ngep->nge_chip_state = NGE_CHIP_RESET;
11316f3e57acSmx205022 	return (DDI_SUCCESS);
11326f3e57acSmx205022 }
11336f3e57acSmx205022 
11346f3e57acSmx205022 int
nge_chip_start(nge_t * ngep)11356f3e57acSmx205022 nge_chip_start(nge_t *ngep)
11366f3e57acSmx205022 {
11376f3e57acSmx205022 	int err;
11386f3e57acSmx205022 	nge_itc itc;
11396f3e57acSmx205022 	nge_tx_cntl tx_cntl;
11406f3e57acSmx205022 	nge_rx_cntrl0 rx_cntl0;
11416f3e57acSmx205022 	nge_rx_cntl1 rx_cntl1;
11426f3e57acSmx205022 	nge_tx_en tx_en;
11436f3e57acSmx205022 	nge_rx_en rx_en;
11446f3e57acSmx205022 	nge_mii_cs mii_cs;
11456f3e57acSmx205022 	nge_swtr_cntl swtr_cntl;
11466f3e57acSmx205022 	nge_rx_fifo_wm rx_fifo;
11476f3e57acSmx205022 	nge_intr_mask intr_mask;
11486f3e57acSmx205022 	nge_mintr_mask mintr_mask;
11496f3e57acSmx205022 	nge_dev_spec_param_t	*dev_param_p;
11506f3e57acSmx205022 
11516f3e57acSmx205022 	NGE_TRACE(("nge_chip_start($%p)", (void *)ngep));
11526f3e57acSmx205022 
11536f3e57acSmx205022 	/*
11546f3e57acSmx205022 	 * Setup buffer management
11556f3e57acSmx205022 	 */
11566f3e57acSmx205022 	err = nge_buff_setup(ngep);
11576f3e57acSmx205022 	if (err == DDI_FAILURE)
11586f3e57acSmx205022 		return (err);
11596f3e57acSmx205022 
11606f3e57acSmx205022 	dev_param_p = &ngep->dev_spec_param;
11616f3e57acSmx205022 
11626f3e57acSmx205022 	/*
11636f3e57acSmx205022 	 * Enable polling attribute
11646f3e57acSmx205022 	 */
11656f3e57acSmx205022 	mii_cs.cs_val = nge_reg_get32(ngep, NGE_MII_CS);
11666f3e57acSmx205022 	mii_cs.cs_bits.ap_paddr = ngep->phy_xmii_addr;
11676f3e57acSmx205022 	mii_cs.cs_bits.ap_en = NGE_SET;
11686f3e57acSmx205022 	mii_cs.cs_bits.ap_intv = MII_POLL_INTV;
11696f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MII_CS, mii_cs.cs_val);
11706f3e57acSmx205022 
11716f3e57acSmx205022 	/*
11726f3e57acSmx205022 	 * Setup link
11736f3e57acSmx205022 	 */
11746f3e57acSmx205022 	(*ngep->physops->phys_update)(ngep);
11756f3e57acSmx205022 
11766f3e57acSmx205022 	/*
11776f3e57acSmx205022 	 * Configure the tx's parameters
11786f3e57acSmx205022 	 */
11796f3e57acSmx205022 	tx_cntl.cntl_val = nge_reg_get32(ngep, NGE_TX_CNTL);
11806f3e57acSmx205022 	if (dev_param_p->tx_pause_frame)
11816f3e57acSmx205022 		tx_cntl.cntl_bits.paen = NGE_SET;
11826f3e57acSmx205022 	else
11836f3e57acSmx205022 		tx_cntl.cntl_bits.paen = NGE_CLEAR;
11846f3e57acSmx205022 	tx_cntl.cntl_bits.retry_en = NGE_SET;
11856f3e57acSmx205022 	tx_cntl.cntl_bits.pad_en = NGE_SET;
11866f3e57acSmx205022 	tx_cntl.cntl_bits.fappend_en = NGE_SET;
11876f3e57acSmx205022 	tx_cntl.cntl_bits.two_def_en = NGE_SET;
11886f3e57acSmx205022 	tx_cntl.cntl_bits.max_retry = 15;
11896f3e57acSmx205022 	tx_cntl.cntl_bits.burst_en = NGE_CLEAR;
11906f3e57acSmx205022 	tx_cntl.cntl_bits.uflo_err_mask = NGE_CLEAR;
11916f3e57acSmx205022 	tx_cntl.cntl_bits.tlcol_mask = NGE_CLEAR;
11926f3e57acSmx205022 	tx_cntl.cntl_bits.lcar_mask = NGE_CLEAR;
11936f3e57acSmx205022 	tx_cntl.cntl_bits.def_mask = NGE_CLEAR;
11946f3e57acSmx205022 	tx_cntl.cntl_bits.exdef_mask = NGE_SET;
11956f3e57acSmx205022 	tx_cntl.cntl_bits.lcar_mask = NGE_SET;
11966f3e57acSmx205022 	tx_cntl.cntl_bits.tlcol_mask = NGE_SET;
11976f3e57acSmx205022 	tx_cntl.cntl_bits.uflo_err_mask = NGE_SET;
11986f3e57acSmx205022 	tx_cntl.cntl_bits.jam_seq_en = NGE_CLEAR;
11996f3e57acSmx205022 	nge_reg_put32(ngep, NGE_TX_CNTL, tx_cntl.cntl_val);
12006f3e57acSmx205022 
12016f3e57acSmx205022 
12026f3e57acSmx205022 	/*
12036f3e57acSmx205022 	 * Configure the parameters of Rx's state machine
12046f3e57acSmx205022 	 * Enabe the parameters:
12056f3e57acSmx205022 	 * 1). Pad Strip
12066f3e57acSmx205022 	 * 2). FCS Relay
12076f3e57acSmx205022 	 * 3). Pause
12086f3e57acSmx205022 	 * 4). Address filter
12096f3e57acSmx205022 	 * 5). Runt Packet receive
12106f3e57acSmx205022 	 * 6). Broadcast
12116f3e57acSmx205022 	 * 7). Receive Deferral
12126f3e57acSmx205022 	 *
12136f3e57acSmx205022 	 * Disable the following parameters for decreasing
12146f3e57acSmx205022 	 * the number of interrupts:
12156f3e57acSmx205022 	 * 1). Runt Inerrupt.
12166f3e57acSmx205022 	 * 2). Rx's Late Collision interrupt.
12176f3e57acSmx205022 	 * 3). Rx's Max length Error Interrupt.
12186f3e57acSmx205022 	 * 4). Rx's Length Field error Interrupt.
12196f3e57acSmx205022 	 * 5). Rx's FCS error interrupt.
12206f3e57acSmx205022 	 * 6). Rx's overflow error interrupt.
12216f3e57acSmx205022 	 * 7). Rx's Frame alignment error interrupt.
12226f3e57acSmx205022 	 */
12236f3e57acSmx205022 	rx_cntl0.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL0);
12246f3e57acSmx205022 	rx_cntl0.cntl_bits.padsen = NGE_CLEAR;
12256f3e57acSmx205022 	rx_cntl0.cntl_bits.fcsren = NGE_CLEAR;
12266f3e57acSmx205022 	if (dev_param_p->rx_pause_frame)
12276f3e57acSmx205022 		rx_cntl0.cntl_bits.paen = NGE_SET;
12286f3e57acSmx205022 	else
12296f3e57acSmx205022 		rx_cntl0.cntl_bits.paen = NGE_CLEAR;
12306f3e57acSmx205022 	rx_cntl0.cntl_bits.lben = NGE_CLEAR;
12316f3e57acSmx205022 	rx_cntl0.cntl_bits.afen = NGE_SET;
12326f3e57acSmx205022 	rx_cntl0.cntl_bits.runten = NGE_CLEAR;
12336f3e57acSmx205022 	rx_cntl0.cntl_bits.brdis = NGE_CLEAR;
12346f3e57acSmx205022 	rx_cntl0.cntl_bits.rdfen = NGE_CLEAR;
12356f3e57acSmx205022 	rx_cntl0.cntl_bits.runtm = NGE_CLEAR;
12366f3e57acSmx205022 	rx_cntl0.cntl_bits.slfb = NGE_CLEAR;
12376f3e57acSmx205022 	rx_cntl0.cntl_bits.rlcolm = NGE_CLEAR;
12386f3e57acSmx205022 	rx_cntl0.cntl_bits.maxerm = NGE_CLEAR;
12396f3e57acSmx205022 	rx_cntl0.cntl_bits.lferm = NGE_CLEAR;
12406f3e57acSmx205022 	rx_cntl0.cntl_bits.crcm = NGE_CLEAR;
12416f3e57acSmx205022 	rx_cntl0.cntl_bits.ofolm = NGE_CLEAR;
12426f3e57acSmx205022 	rx_cntl0.cntl_bits.framerm = NGE_CLEAR;
12436f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl0.cntl_val);
12446f3e57acSmx205022 
12456f3e57acSmx205022 	/*
12466f3e57acSmx205022 	 * Configure the watermark for the rx's statemachine
12476f3e57acSmx205022 	 */
12486f3e57acSmx205022 	rx_fifo.wm_val = nge_reg_get32(ngep, NGE_RX_FIFO_WM);
12496f3e57acSmx205022 	rx_fifo.wm_bits.data_hwm = ngep->rx_datahwm;
12506f3e57acSmx205022 	rx_fifo.wm_bits.prd_lwm = ngep->rx_prdlwm;
12516f3e57acSmx205022 	rx_fifo.wm_bits.prd_hwm = ngep->rx_prdhwm;
12526f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_FIFO_WM, rx_fifo.wm_val);
12536f3e57acSmx205022 
12546f3e57acSmx205022 	/*
12556f3e57acSmx205022 	 * Configure the deffer time slot for rx's state machine
12566f3e57acSmx205022 	 */
12576f3e57acSmx205022 	nge_reg_put8(ngep, NGE_RX_DEf, ngep->rx_def);
12586f3e57acSmx205022 
12596f3e57acSmx205022 	/*
12606f3e57acSmx205022 	 * Configure the length of rx's packet
12616f3e57acSmx205022 	 */
12626f3e57acSmx205022 	rx_cntl1.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL1);
12636f3e57acSmx205022 	rx_cntl1.cntl_bits.length = ngep->max_sdu;
12646f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_CNTL1, rx_cntl1.cntl_val);
12656f3e57acSmx205022 	/*
12666f3e57acSmx205022 	 * Enable Tx's state machine
12676f3e57acSmx205022 	 */
12686f3e57acSmx205022 	tx_en.val = nge_reg_get8(ngep, NGE_TX_EN);
12696f3e57acSmx205022 	tx_en.bits.tx_en = NGE_SET;
12706f3e57acSmx205022 	nge_reg_put8(ngep, NGE_TX_EN, tx_en.val);
12716f3e57acSmx205022 
12726f3e57acSmx205022 	/*
12736f3e57acSmx205022 	 * Enable Rx's state machine
12746f3e57acSmx205022 	 */
12756f3e57acSmx205022 	rx_en.val = nge_reg_get8(ngep, NGE_RX_EN);
12766f3e57acSmx205022 	rx_en.bits.rx_en = NGE_SET;
12776f3e57acSmx205022 	nge_reg_put8(ngep, NGE_RX_EN, rx_en.val);
12786f3e57acSmx205022 
12796f3e57acSmx205022 	itc.itc_val = nge_reg_get32(ngep, NGE_SWTR_ITC);
12806f3e57acSmx205022 	itc.itc_bits.sw_intv = ngep->sw_intr_intv;
12816f3e57acSmx205022 	nge_reg_put32(ngep, NGE_SWTR_ITC, itc.itc_val);
12826f3e57acSmx205022 
12836f3e57acSmx205022 	swtr_cntl.ctrl_val = nge_reg_get8(ngep, NGE_SWTR_CNTL);
12846f3e57acSmx205022 	swtr_cntl.cntl_bits.sten = NGE_SET;
12856f3e57acSmx205022 	swtr_cntl.cntl_bits.stren = NGE_SET;
12866f3e57acSmx205022 	nge_reg_put32(ngep, NGE_SWTR_CNTL, swtr_cntl.ctrl_val);
12876f3e57acSmx205022 
12886f3e57acSmx205022 	/*
12896f3e57acSmx205022 	 * Disable all mii read/write operation Interrupt
12906f3e57acSmx205022 	 */
12916f3e57acSmx205022 	mintr_mask.mask_val = nge_reg_get8(ngep, NGE_MINTR_MASK);
12926f3e57acSmx205022 	mintr_mask.mask_bits.mrei = NGE_CLEAR;
12936f3e57acSmx205022 	mintr_mask.mask_bits.mcc2 = NGE_CLEAR;
12946f3e57acSmx205022 	mintr_mask.mask_bits.mcc1 = NGE_CLEAR;
12956f3e57acSmx205022 	mintr_mask.mask_bits.mapi = NGE_SET;
12966f3e57acSmx205022 	mintr_mask.mask_bits.mpdi = NGE_SET;
12976f3e57acSmx205022 	nge_reg_put8(ngep, NGE_MINTR_MASK, mintr_mask.mask_val);
12986f3e57acSmx205022 
12996f3e57acSmx205022 	/*
13006f3e57acSmx205022 	 * Enable all interrupt event
13016f3e57acSmx205022 	 */
13026f3e57acSmx205022 	intr_mask.mask_val = nge_reg_get32(ngep, NGE_INTR_MASK);
13036f3e57acSmx205022 	intr_mask.mask_bits.reint = NGE_SET;
13046f3e57acSmx205022 	intr_mask.mask_bits.rcint = NGE_SET;
13056f3e57acSmx205022 	intr_mask.mask_bits.miss = NGE_SET;
1306*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	intr_mask.mask_bits.teint = NGE_SET;
1307*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	intr_mask.mask_bits.tcint = NGE_CLEAR;
13086f3e57acSmx205022 	intr_mask.mask_bits.stint = NGE_CLEAR;
13096f3e57acSmx205022 	intr_mask.mask_bits.mint = NGE_CLEAR;
13106f3e57acSmx205022 	intr_mask.mask_bits.rfint = NGE_CLEAR;
1311*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	intr_mask.mask_bits.tfint = NGE_SET;
13126f3e57acSmx205022 	intr_mask.mask_bits.feint = NGE_SET;
13136f3e57acSmx205022 	intr_mask.mask_bits.resv10 = NGE_CLEAR;
13146f3e57acSmx205022 	intr_mask.mask_bits.resv11 = NGE_CLEAR;
13156f3e57acSmx205022 	intr_mask.mask_bits.resv12 = NGE_CLEAR;
13166f3e57acSmx205022 	intr_mask.mask_bits.resv13 = NGE_CLEAR;
13176f3e57acSmx205022 	intr_mask.mask_bits.phyint = NGE_CLEAR;
13186f3e57acSmx205022 	ngep->intr_masks = intr_mask.mask_val;
13196f3e57acSmx205022 	nge_reg_put32(ngep, NGE_INTR_MASK, intr_mask.mask_val);
13206f3e57acSmx205022 	ngep->nge_chip_state = NGE_CHIP_RUNNING;
13216f3e57acSmx205022 	return (DDI_SUCCESS);
13226f3e57acSmx205022 }
13236f3e57acSmx205022 
13246f3e57acSmx205022 /*
13256f3e57acSmx205022  * nge_chip_sync() -- program the chip with the unicast MAC address,
13266f3e57acSmx205022  * the multicast hash table, the required level of promiscuity.
13276f3e57acSmx205022  */
13286f3e57acSmx205022 void
nge_chip_sync(nge_t * ngep)13296f3e57acSmx205022 nge_chip_sync(nge_t *ngep)
13306f3e57acSmx205022 {
13316f3e57acSmx205022 	uint8_t i;
13326f3e57acSmx205022 	uint64_t macaddr;
13336f3e57acSmx205022 	uint64_t mul_addr;
13346f3e57acSmx205022 	uint64_t mul_mask;
13356f3e57acSmx205022 	nge_rx_cntrl0 rx_cntl;
13366f3e57acSmx205022 	nge_uni_addr1 uni_adr1;
13376f3e57acSmx205022 
13386f3e57acSmx205022 	NGE_TRACE(("nge_chip_sync($%p)", (void *)ngep));
13396f3e57acSmx205022 
13406f3e57acSmx205022 	macaddr = 0x0ull;
13416f3e57acSmx205022 	mul_addr = 0x0ull;
13426f3e57acSmx205022 	mul_mask = 0x0ull;
13436f3e57acSmx205022 	rx_cntl.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL0);
13446f3e57acSmx205022 
13456f3e57acSmx205022 	if (ngep->promisc) {
13466f3e57acSmx205022 		rx_cntl.cntl_bits.afen = NGE_CLEAR;
13476f3e57acSmx205022 		rx_cntl.cntl_bits.brdis = NGE_SET;
13486f3e57acSmx205022 	} else {
13496f3e57acSmx205022 		rx_cntl.cntl_bits.afen = NGE_SET;
13506f3e57acSmx205022 		rx_cntl.cntl_bits.brdis = NGE_CLEAR;
13516f3e57acSmx205022 	}
13526f3e57acSmx205022 
13536f3e57acSmx205022 	/*
13546f3e57acSmx205022 	 * Transform the MAC address from host to chip format, the unicast
13556f3e57acSmx205022 	 * MAC address(es) ...
13566f3e57acSmx205022 	 */
13576f3e57acSmx205022 	for (i = ETHERADDRL, macaddr = 0ull; i != 0; --i) {
13586f3e57acSmx205022 		macaddr |= ngep->cur_uni_addr.addr[i-1];
13596f3e57acSmx205022 		macaddr <<= (i > 1) ? 8 : 0;
13606f3e57acSmx205022 	}
13616f3e57acSmx205022 
13626f3e57acSmx205022 	nge_reg_put32(ngep, NGE_UNI_ADDR0, (uint32_t)macaddr);
13636f3e57acSmx205022 	macaddr = macaddr >>32;
13646f3e57acSmx205022 	uni_adr1.addr_val = nge_reg_get32(ngep, NGE_UNI_ADDR1);
13656f3e57acSmx205022 	uni_adr1.addr_bits.addr = (uint16_t)macaddr;
13666f3e57acSmx205022 	uni_adr1.addr_bits.resv16_31 = (uint16_t)0;
13676f3e57acSmx205022 	nge_reg_put32(ngep, NGE_UNI_ADDR1, uni_adr1.addr_val);
13686f3e57acSmx205022 
13696f3e57acSmx205022 	/*
13706f3e57acSmx205022 	 * Reprogram the  multicast address table ...
13716f3e57acSmx205022 	 */
13726f3e57acSmx205022 	for (i = ETHERADDRL, mul_addr = 0ull; i != 0; --i) {
13736f3e57acSmx205022 		mul_addr |= ngep->cur_mul_addr.addr[i-1];
13746f3e57acSmx205022 		mul_addr <<= (i > 1) ? 8 : 0;
13756f3e57acSmx205022 		mul_mask |= ngep->cur_mul_mask.addr[i-1];
13766f3e57acSmx205022 		mul_mask <<= (i > 1) ? 8 : 0;
13776f3e57acSmx205022 	}
13786f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MUL_ADDR0, (uint32_t)mul_addr);
13796f3e57acSmx205022 	mul_addr >>= 32;
13806f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MUL_ADDR1, mul_addr);
13816f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MUL_MASK, (uint32_t)mul_mask);
13826f3e57acSmx205022 	mul_mask >>= 32;
13836f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MUL_MASK1, mul_mask);
13846f3e57acSmx205022 	/*
13856f3e57acSmx205022 	 * Set or clear the PROMISCUOUS mode bit
13866f3e57acSmx205022 	 */
13876f3e57acSmx205022 	nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl.cntl_val);
13886f3e57acSmx205022 	/*
13896f3e57acSmx205022 	 * For internal PHY loopback, the link will
13906f3e57acSmx205022 	 * not be up, so it need to sync mac modes directly.
13916f3e57acSmx205022 	 */
13926f3e57acSmx205022 	if (ngep->param_loop_mode == NGE_LOOP_INTERNAL_PHY)
13936f3e57acSmx205022 		nge_sync_mac_modes(ngep);
13946f3e57acSmx205022 }
13956f3e57acSmx205022 
13966f3e57acSmx205022 static void
nge_chip_err(nge_t * ngep)13976f3e57acSmx205022 nge_chip_err(nge_t *ngep)
13986f3e57acSmx205022 {
13996f3e57acSmx205022 	nge_reg010 reg010_ins;
14006f3e57acSmx205022 	nge_sw_statistics_t *psw_stat;
14016f3e57acSmx205022 	nge_intr_mask intr_mask;
14026f3e57acSmx205022 
14036f3e57acSmx205022 	NGE_TRACE(("nge_chip_err($%p)", (void *)ngep));
14046f3e57acSmx205022 
14056f3e57acSmx205022 	psw_stat = (nge_sw_statistics_t *)&ngep->statistics.sw_statistics;
14066f3e57acSmx205022 	reg010_ins.reg010_val = nge_reg_get32(ngep, NGE_REG010);
14076f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv0)
14086f3e57acSmx205022 		psw_stat->fe_err.tso_err_mss ++;
14096f3e57acSmx205022 
14106f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv1)
14116f3e57acSmx205022 		psw_stat->fe_err.tso_dis ++;
14126f3e57acSmx205022 
14136f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv2)
14146f3e57acSmx205022 		psw_stat->fe_err.tso_err_nosum ++;
14156f3e57acSmx205022 
14166f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv3)
14176f3e57acSmx205022 		psw_stat->fe_err.tso_err_hov ++;
14186f3e57acSmx205022 
14196f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv4)
14206f3e57acSmx205022 		psw_stat->fe_err.tso_err_huf ++;
14216f3e57acSmx205022 
14226f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv5)
14236f3e57acSmx205022 		psw_stat->fe_err.tso_err_l2 ++;
14246f3e57acSmx205022 
14256f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv6)
14266f3e57acSmx205022 		psw_stat->fe_err.tso_err_ip ++;
14276f3e57acSmx205022 
14286f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv7)
14296f3e57acSmx205022 		psw_stat->fe_err.tso_err_l4 ++;
14306f3e57acSmx205022 
14316f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv8)
14326f3e57acSmx205022 		psw_stat->fe_err.tso_err_tcp ++;
14336f3e57acSmx205022 
14346f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv9)
14356f3e57acSmx205022 		psw_stat->fe_err.hsum_err_ip ++;
14366f3e57acSmx205022 
14376f3e57acSmx205022 	if (reg010_ins.reg010_bits.resv10)
14386f3e57acSmx205022 		psw_stat->fe_err.hsum_err_l4 ++;
14396f3e57acSmx205022 
14406f3e57acSmx205022 	if (reg010_ins.reg010_val != 0) {
14416f3e57acSmx205022 
14426f3e57acSmx205022 		/*
14436f3e57acSmx205022 		 * Fatal error is triggered by malformed driver commands.
14446f3e57acSmx205022 		 * Disable unless debugging.
14456f3e57acSmx205022 		 */
14466f3e57acSmx205022 		intr_mask.mask_val = nge_reg_get32(ngep, NGE_INTR_MASK);
14476f3e57acSmx205022 		intr_mask.mask_bits.feint = NGE_CLEAR;
14486f3e57acSmx205022 		nge_reg_put32(ngep, NGE_INTR_MASK, intr_mask.mask_val);
14496f3e57acSmx205022 		ngep->intr_masks = intr_mask.mask_val;
14506f3e57acSmx205022 
14516f3e57acSmx205022 	}
14526f3e57acSmx205022 }
14536f3e57acSmx205022 
14546f3e57acSmx205022 static void
nge_sync_mac_modes(nge_t * ngep)14556f3e57acSmx205022 nge_sync_mac_modes(nge_t *ngep)
14566f3e57acSmx205022 {
14576f3e57acSmx205022 	nge_tx_def tx_def;
14586f3e57acSmx205022 	nge_tx_fifo_wm tx_fifo;
14596f3e57acSmx205022 	nge_bkoff_cntl bk_cntl;
14606f3e57acSmx205022 	nge_mac2phy m2p;
14616f3e57acSmx205022 	nge_rx_cntrl0 rx_cntl0;
146286d6718fSLi-Zhen You 	nge_tx_cntl tx_cntl;
14636f3e57acSmx205022 	nge_dev_spec_param_t	*dev_param_p;
14646f3e57acSmx205022 
14656f3e57acSmx205022 	dev_param_p = &ngep->dev_spec_param;
14666f3e57acSmx205022 
14676f3e57acSmx205022 	tx_def.def_val = nge_reg_get32(ngep, NGE_TX_DEF);
14686f3e57acSmx205022 	m2p.m2p_val = nge_reg_get32(ngep, NGE_MAC2PHY);
14696f3e57acSmx205022 	tx_fifo.wm_val = nge_reg_get32(ngep, NGE_TX_FIFO_WM);
14706f3e57acSmx205022 	bk_cntl.cntl_val = nge_reg_get32(ngep, NGE_BKOFF_CNTL);
14716f3e57acSmx205022 	bk_cntl.bkoff_bits.rseed = BKOFF_RSEED;
14726f3e57acSmx205022 	switch (ngep->param_link_speed) {
14736f3e57acSmx205022 	case 10:
14746f3e57acSmx205022 		m2p.m2p_bits.speed = low_speed;
14756f3e57acSmx205022 		tx_def.def_bits.ifg1_def = TX_IFG1_DEFAULT;
14766f3e57acSmx205022 		if (ngep->phy_mode == RGMII_IN) {
14776f3e57acSmx205022 			tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_10_100;
14786f3e57acSmx205022 			tx_def.def_bits.if_def = TX_IFG_RGMII_OTHER;
14796f3e57acSmx205022 		} else {
14806f3e57acSmx205022 			tx_def.def_bits.if_def = TX_TIFG_MII;
14816f3e57acSmx205022 			tx_def.def_bits.ifg2_def = TX_IFG2_MII;
14826f3e57acSmx205022 		}
14836f3e57acSmx205022 		tx_fifo.wm_bits.nbfb_wm = TX_FIFO_NOB_WM_MII;
14846f3e57acSmx205022 		bk_cntl.bkoff_bits.sltm = BKOFF_SLIM_MII;
14856f3e57acSmx205022 		break;
14866f3e57acSmx205022 
14876f3e57acSmx205022 	case 100:
14886f3e57acSmx205022 		m2p.m2p_bits.speed = fast_speed;
14896f3e57acSmx205022 		tx_def.def_bits.ifg1_def = TX_IFG1_DEFAULT;
14906f3e57acSmx205022 		if (ngep->phy_mode == RGMII_IN) {
14916f3e57acSmx205022 			tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_10_100;
14926f3e57acSmx205022 			tx_def.def_bits.if_def = TX_IFG_RGMII_OTHER;
14936f3e57acSmx205022 		} else {
14946f3e57acSmx205022 			tx_def.def_bits.if_def = TX_TIFG_MII;
14956f3e57acSmx205022 			tx_def.def_bits.ifg2_def = TX_IFG2_MII;
14966f3e57acSmx205022 		}
14976f3e57acSmx205022 		tx_fifo.wm_bits.nbfb_wm = TX_FIFO_NOB_WM_MII;
14986f3e57acSmx205022 		bk_cntl.bkoff_bits.sltm = BKOFF_SLIM_MII;
14996f3e57acSmx205022 		break;
15006f3e57acSmx205022 
15016f3e57acSmx205022 	case 1000:
15026f3e57acSmx205022 		m2p.m2p_bits.speed = giga_speed;
15036f3e57acSmx205022 		tx_def.def_bits.ifg1_def = TX_IFG1_DEFAULT;
15046f3e57acSmx205022 		if (ngep->param_link_duplex == LINK_DUPLEX_FULL) {
15056f3e57acSmx205022 			tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_1000;
15066f3e57acSmx205022 			tx_def.def_bits.if_def = TX_IFG_RGMII_1000_FD;
15076f3e57acSmx205022 		} else {
15086f3e57acSmx205022 			tx_def.def_bits.ifg2_def = TX_IFG2_RGMII_1000;
15096f3e57acSmx205022 			tx_def.def_bits.if_def = TX_IFG_RGMII_OTHER;
15106f3e57acSmx205022 		}
15116f3e57acSmx205022 
15126f3e57acSmx205022 		tx_fifo.wm_bits.nbfb_wm = TX_FIFO_NOB_WM_GMII;
15136f3e57acSmx205022 		bk_cntl.bkoff_bits.sltm = BKOFF_SLIM_GMII;
15146f3e57acSmx205022 		break;
15156f3e57acSmx205022 	}
15166f3e57acSmx205022 
15176f3e57acSmx205022 	if (ngep->chipinfo.device == DEVICE_ID_MCP55_373 ||
15186f3e57acSmx205022 	    ngep->chipinfo.device == DEVICE_ID_MCP55_372) {
15196f3e57acSmx205022 		m2p.m2p_bits.phyintr = NGE_CLEAR;
15206f3e57acSmx205022 		m2p.m2p_bits.phyintrlvl = NGE_CLEAR;
15216f3e57acSmx205022 	}
15226f3e57acSmx205022 	if (ngep->param_link_duplex == LINK_DUPLEX_HALF) {
15236f3e57acSmx205022 		m2p.m2p_bits.hdup_en = NGE_SET;
15246f3e57acSmx205022 	}
15256f3e57acSmx205022 	else
15266f3e57acSmx205022 		m2p.m2p_bits.hdup_en = NGE_CLEAR;
15276f3e57acSmx205022 	nge_reg_put32(ngep, NGE_MAC2PHY, m2p.m2p_val);
15286f3e57acSmx205022 	nge_reg_put32(ngep, NGE_TX_DEF, tx_def.def_val);
15296f3e57acSmx205022 
15306f3e57acSmx205022 	tx_fifo.wm_bits.data_lwm = TX_FIFO_DATA_LWM;
15316f3e57acSmx205022 	tx_fifo.wm_bits.prd_lwm = TX_FIFO_PRD_LWM;
15326f3e57acSmx205022 	tx_fifo.wm_bits.uprd_hwm = TX_FIFO_PRD_HWM;
15336f3e57acSmx205022 	tx_fifo.wm_bits.fb_wm = TX_FIFO_TBFW;
15346f3e57acSmx205022 	nge_reg_put32(ngep, NGE_TX_FIFO_WM, tx_fifo.wm_val);
15356f3e57acSmx205022 
15366f3e57acSmx205022 	nge_reg_put32(ngep, NGE_BKOFF_CNTL, bk_cntl.cntl_val);
15376f3e57acSmx205022 
15386f3e57acSmx205022 	rx_cntl0.cntl_val = nge_reg_get32(ngep, NGE_RX_CNTL0);
153986d6718fSLi-Zhen You 	if (ngep->param_link_rx_pause && dev_param_p->rx_pause_frame) {
154086d6718fSLi-Zhen You 		if (rx_cntl0.cntl_bits.paen == NGE_CLEAR) {
15416f3e57acSmx205022 			rx_cntl0.cntl_bits.paen = NGE_SET;
154286d6718fSLi-Zhen You 			nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl0.cntl_val);
154386d6718fSLi-Zhen You 	}
154486d6718fSLi-Zhen You 	} else {
154586d6718fSLi-Zhen You 		if (rx_cntl0.cntl_bits.paen == NGE_SET) {
15466f3e57acSmx205022 			rx_cntl0.cntl_bits.paen = NGE_CLEAR;
15476f3e57acSmx205022 			nge_reg_put32(ngep, NGE_RX_CNTL0, rx_cntl0.cntl_val);
15486f3e57acSmx205022 		}
154986d6718fSLi-Zhen You 	}
155086d6718fSLi-Zhen You 
155186d6718fSLi-Zhen You 	tx_cntl.cntl_val = nge_reg_get32(ngep, NGE_TX_CNTL);
155286d6718fSLi-Zhen You 	if (ngep->param_link_tx_pause && dev_param_p->tx_pause_frame) {
155386d6718fSLi-Zhen You 		if (tx_cntl.cntl_bits.paen == NGE_CLEAR) {
155486d6718fSLi-Zhen You 			tx_cntl.cntl_bits.paen = NGE_SET;
155586d6718fSLi-Zhen You 			nge_reg_put32(ngep, NGE_TX_CNTL, tx_cntl.cntl_val);
155686d6718fSLi-Zhen You 		}
155786d6718fSLi-Zhen You 	} else {
155886d6718fSLi-Zhen You 		if (tx_cntl.cntl_bits.paen == NGE_SET) {
155986d6718fSLi-Zhen You 			tx_cntl.cntl_bits.paen = NGE_CLEAR;
156086d6718fSLi-Zhen You 			nge_reg_put32(ngep, NGE_TX_CNTL, tx_cntl.cntl_val);
156186d6718fSLi-Zhen You 		}
156286d6718fSLi-Zhen You 	}
156386d6718fSLi-Zhen You }
15646f3e57acSmx205022 
15656f3e57acSmx205022 /*
15666f3e57acSmx205022  * Handler for hardware link state change.
15676f3e57acSmx205022  *
15686f3e57acSmx205022  * When this routine is called, the hardware link state has changed
15696f3e57acSmx205022  * and the new state is reflected in the param_* variables.  Here
15706f3e57acSmx205022  * we must update the softstate, reprogram the MAC to match, and
15716f3e57acSmx205022  * record the change in the log and/or on the console.
15726f3e57acSmx205022  */
15736f3e57acSmx205022 static void
nge_factotum_link_handler(nge_t * ngep)15746f3e57acSmx205022 nge_factotum_link_handler(nge_t *ngep)
15756f3e57acSmx205022 {
15766f3e57acSmx205022 	/*
15776f3e57acSmx205022 	 * Update the s/w link_state
15786f3e57acSmx205022 	 */
15796f3e57acSmx205022 	if (ngep->param_link_up)
15806f3e57acSmx205022 		ngep->link_state = LINK_STATE_UP;
15816f3e57acSmx205022 	else
15826f3e57acSmx205022 		ngep->link_state = LINK_STATE_DOWN;
15836f3e57acSmx205022 
15846f3e57acSmx205022 	/*
15856f3e57acSmx205022 	 * Reprogram the MAC modes to match
15866f3e57acSmx205022 	 */
15876f3e57acSmx205022 	nge_sync_mac_modes(ngep);
15886f3e57acSmx205022 }
15896f3e57acSmx205022 
15906f3e57acSmx205022 static boolean_t
nge_factotum_link_check(nge_t * ngep)15916f3e57acSmx205022 nge_factotum_link_check(nge_t *ngep)
15926f3e57acSmx205022 {
15936f3e57acSmx205022 	boolean_t lchg;
15946f3e57acSmx205022 	boolean_t check;
15956f3e57acSmx205022 
15966f3e57acSmx205022 	ASSERT(mutex_owned(ngep->genlock));
15976f3e57acSmx205022 
15986f3e57acSmx205022 	(*ngep->physops->phys_check)(ngep);
15996f3e57acSmx205022 	switch (ngep->link_state) {
16006f3e57acSmx205022 	case LINK_STATE_UP:
16016f3e57acSmx205022 		lchg = (ngep->param_link_up == B_FALSE);
16026f3e57acSmx205022 		check = (ngep->param_link_up == B_FALSE);
16036f3e57acSmx205022 		break;
16046f3e57acSmx205022 
16056f3e57acSmx205022 	case LINK_STATE_DOWN:
16066f3e57acSmx205022 		lchg = (ngep->param_link_up == B_TRUE);
16076f3e57acSmx205022 		check = (ngep->param_link_up == B_TRUE);
16086f3e57acSmx205022 		break;
16096f3e57acSmx205022 
16106f3e57acSmx205022 	default:
16116f3e57acSmx205022 		check = B_TRUE;
16126f3e57acSmx205022 		break;
16136f3e57acSmx205022 	}
16146f3e57acSmx205022 
16156f3e57acSmx205022 	/*
16166f3e57acSmx205022 	 * If <check> is false, we're sure the link hasn't changed.
16176f3e57acSmx205022 	 * If true, however, it's not yet definitive; we have to call
16186f3e57acSmx205022 	 * nge_phys_check() to determine whether the link has settled
16196f3e57acSmx205022 	 * into a new state yet ... and if it has, then call the link
16206f3e57acSmx205022 	 * state change handler.But when the chip is 5700 in Dell 6650
16216f3e57acSmx205022 	 * ,even if check is false, the link may have changed.So we
16226f3e57acSmx205022 	 * have to call nge_phys_check() to determine the link state.
16236f3e57acSmx205022 	 */
16246f3e57acSmx205022 	if (check)
16256f3e57acSmx205022 		nge_factotum_link_handler(ngep);
16266f3e57acSmx205022 
16276f3e57acSmx205022 	return (lchg);
16286f3e57acSmx205022 }
16296f3e57acSmx205022 
16306f3e57acSmx205022 /*
16316f3e57acSmx205022  * Factotum routine to check for Tx stall, using the 'watchdog' counter
16326f3e57acSmx205022  */
16336f3e57acSmx205022 static boolean_t nge_factotum_stall_check(nge_t *ngep);
16346f3e57acSmx205022 
16356f3e57acSmx205022 static boolean_t
nge_factotum_stall_check(nge_t * ngep)16366f3e57acSmx205022 nge_factotum_stall_check(nge_t *ngep)
16376f3e57acSmx205022 {
16386f3e57acSmx205022 	uint32_t dogval;
1639*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	send_ring_t *srp;
1640*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	srp = ngep->send;
16416f3e57acSmx205022 	/*
16426f3e57acSmx205022 	 * Specific check for Tx stall ...
16436f3e57acSmx205022 	 *
16446f3e57acSmx205022 	 * The 'watchdog' counter is incremented whenever a packet
16456f3e57acSmx205022 	 * is queued, reset to 1 when some (but not all) buffers
16466f3e57acSmx205022 	 * are reclaimed, reset to 0 (disabled) when all buffers
16476f3e57acSmx205022 	 * are reclaimed, and shifted left here.  If it exceeds the
16486f3e57acSmx205022 	 * threshold value, the chip is assumed to have stalled and
16496f3e57acSmx205022 	 * is put into the ERROR state.  The factotum will then reset
16506f3e57acSmx205022 	 * it on the next pass.
16516f3e57acSmx205022 	 *
16526f3e57acSmx205022 	 * All of which should ensure that we don't get into a state
16536f3e57acSmx205022 	 * where packets are left pending indefinitely!
16546f3e57acSmx205022 	 */
1655*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	if (ngep->watchdog == 0 &&
1656*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	    srp->tx_free < srp->desc.nslots)
1657*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 		ngep->watchdog = 1;
16586f3e57acSmx205022 	dogval = nge_atomic_shl32(&ngep->watchdog, 1);
1659*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	if (dogval >= nge_watchdog_check)
1660*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 		nge_tx_recycle(ngep, B_FALSE);
1661*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	if (dogval < nge_watchdog_count)
16626f3e57acSmx205022 		return (B_FALSE);
1663*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	else {
16646f3e57acSmx205022 		ngep->statistics.sw_statistics.tx_stall++;
16656f3e57acSmx205022 		return (B_TRUE);
16666f3e57acSmx205022 	}
16676f3e57acSmx205022 }
16686f3e57acSmx205022 
16696f3e57acSmx205022 
16706f3e57acSmx205022 /*
16716f3e57acSmx205022  * The factotum is woken up when there's something to do that we'd rather
16726f3e57acSmx205022  * not do from inside a hardware interrupt handler or high-level cyclic.
16736f3e57acSmx205022  * Its two main tasks are:
16746f3e57acSmx205022  *	reset & restart the chip after an error
16756f3e57acSmx205022  *	check the link status whenever necessary
16766f3e57acSmx205022  */
16776f3e57acSmx205022 /* ARGSUSED */
16786f3e57acSmx205022 uint_t
nge_chip_factotum(caddr_t args1,caddr_t args2)16796f3e57acSmx205022 nge_chip_factotum(caddr_t args1, caddr_t args2)
16806f3e57acSmx205022 {
16816f3e57acSmx205022 	uint_t result;
16826f3e57acSmx205022 	nge_t *ngep;
16836f3e57acSmx205022 	boolean_t err;
16846f3e57acSmx205022 	boolean_t linkchg;
16856f3e57acSmx205022 
16866f3e57acSmx205022 	ngep = (nge_t *)args1;
16876f3e57acSmx205022 
16886f3e57acSmx205022 	NGE_TRACE(("nge_chip_factotum($%p)", (void *)ngep));
16896f3e57acSmx205022 
16906f3e57acSmx205022 	mutex_enter(ngep->softlock);
16916f3e57acSmx205022 	if (ngep->factotum_flag == 0) {
16926f3e57acSmx205022 		mutex_exit(ngep->softlock);
16936f3e57acSmx205022 		return (DDI_INTR_UNCLAIMED);
16946f3e57acSmx205022 	}
16956f3e57acSmx205022 	ngep->factotum_flag = 0;
16966f3e57acSmx205022 	mutex_exit(ngep->softlock);
16976f3e57acSmx205022 	err = B_FALSE;
16986f3e57acSmx205022 	linkchg = B_FALSE;
16996f3e57acSmx205022 	result = DDI_INTR_CLAIMED;
17006f3e57acSmx205022 
17016f3e57acSmx205022 	mutex_enter(ngep->genlock);
17026f3e57acSmx205022 	switch (ngep->nge_chip_state) {
17036f3e57acSmx205022 	default:
17046f3e57acSmx205022 		break;
17056f3e57acSmx205022 
17066f3e57acSmx205022 	case NGE_CHIP_RUNNING:
17076f3e57acSmx205022 		linkchg = nge_factotum_link_check(ngep);
17086f3e57acSmx205022 		err = nge_factotum_stall_check(ngep);
17096f3e57acSmx205022 		break;
17106f3e57acSmx205022 
17116f3e57acSmx205022 	case NGE_CHIP_FAULT:
17126f3e57acSmx205022 		(void) nge_restart(ngep);
17136f3e57acSmx205022 		NGE_REPORT((ngep, "automatic recovery activated"));
17146f3e57acSmx205022 		break;
17156f3e57acSmx205022 	}
17166f3e57acSmx205022 
17176f3e57acSmx205022 	if (err)
17186f3e57acSmx205022 		(void) nge_chip_stop(ngep, B_TRUE);
17196f3e57acSmx205022 	mutex_exit(ngep->genlock);
17206f3e57acSmx205022 
17216f3e57acSmx205022 	/*
17226f3e57acSmx205022 	 * If the link state changed, tell the world about it (if
17236f3e57acSmx205022 	 * this version of MAC supports link state notification).
17246f3e57acSmx205022 	 * Note: can't do this while still holding the mutex.
17256f3e57acSmx205022 	 */
17266f3e57acSmx205022 	if (linkchg)
17276f3e57acSmx205022 		mac_link_update(ngep->mh, ngep->link_state);
17286f3e57acSmx205022 
17296f3e57acSmx205022 	return (result);
17306f3e57acSmx205022 
17316f3e57acSmx205022 }
17326f3e57acSmx205022 
17336f3e57acSmx205022 static void
nge_intr_handle(nge_t * ngep,nge_intr_src * pintr_src)17346f3e57acSmx205022 nge_intr_handle(nge_t *ngep, nge_intr_src *pintr_src)
17356f3e57acSmx205022 {
17366f3e57acSmx205022 	boolean_t brx;
17376f3e57acSmx205022 	boolean_t btx;
17386f3e57acSmx205022 	nge_mintr_src mintr_src;
17396f3e57acSmx205022 
17406f3e57acSmx205022 	brx = B_FALSE;
17416f3e57acSmx205022 	btx = B_FALSE;
17426f3e57acSmx205022 	ngep->statistics.sw_statistics.intr_count++;
17436f3e57acSmx205022 	ngep->statistics.sw_statistics.intr_lval = pintr_src->intr_val;
17446f3e57acSmx205022 	brx = (pintr_src->int_bits.reint | pintr_src->int_bits.miss
17456f3e57acSmx205022 	    | pintr_src->int_bits.rcint | pintr_src->int_bits.stint)
1746b2fa2f2bSjj146644 	    != 0 ? B_TRUE : B_FALSE;
17476f3e57acSmx205022 	if (pintr_src->int_bits.reint)
17486f3e57acSmx205022 		ngep->statistics.sw_statistics.rx_err++;
17496f3e57acSmx205022 	if (pintr_src->int_bits.miss)
17506f3e57acSmx205022 		ngep->statistics.sw_statistics.rx_nobuffer++;
17516f3e57acSmx205022 
1752*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	btx = (pintr_src->int_bits.teint | pintr_src->int_bits.tfint)
1753b2fa2f2bSjj146644 	    != 0 ? B_TRUE : B_FALSE;
17546f3e57acSmx205022 	if (btx)
17556f3e57acSmx205022 		nge_tx_recycle(ngep, B_TRUE);
1756b2fa2f2bSjj146644 	if (brx)
1757b2fa2f2bSjj146644 		nge_receive(ngep);
17586f3e57acSmx205022 	if (pintr_src->int_bits.teint)
17596f3e57acSmx205022 		ngep->statistics.sw_statistics.tx_stop_err++;
176002d51d0dSjj146644 	if (ngep->intr_moderation && brx) {
176102d51d0dSjj146644 		if (ngep->poll) {
176202d51d0dSjj146644 			if (ngep->recv_count < ngep->param_rx_intr_hwater) {
176302d51d0dSjj146644 				ngep->quiet_time++;
176402d51d0dSjj146644 				if (ngep->quiet_time ==
176502d51d0dSjj146644 				    ngep->param_poll_quiet_time) {
17666f3e57acSmx205022 					ngep->poll = B_FALSE;
176702d51d0dSjj146644 					ngep->quiet_time = 0;
176802d51d0dSjj146644 				}
176902d51d0dSjj146644 			} else
177002d51d0dSjj146644 				ngep->quiet_time = 0;
177102d51d0dSjj146644 		} else {
177202d51d0dSjj146644 			if (ngep->recv_count > ngep->param_rx_intr_lwater) {
177302d51d0dSjj146644 				ngep->busy_time++;
177402d51d0dSjj146644 				if (ngep->busy_time ==
177502d51d0dSjj146644 				    ngep->param_poll_busy_time) {
177602d51d0dSjj146644 					ngep->poll = B_TRUE;
177702d51d0dSjj146644 					ngep->busy_time = 0;
177802d51d0dSjj146644 				}
177902d51d0dSjj146644 			} else
178002d51d0dSjj146644 				ngep->busy_time = 0;
178102d51d0dSjj146644 		}
17826f3e57acSmx205022 	}
17836f3e57acSmx205022 	ngep->recv_count = 0;
17846f3e57acSmx205022 	if (pintr_src->int_bits.feint)
17856f3e57acSmx205022 		nge_chip_err(ngep);
17866f3e57acSmx205022 	/* link interrupt, check the link state */
17876f3e57acSmx205022 	if (pintr_src->int_bits.mint) {
17886f3e57acSmx205022 		mintr_src.src_val = nge_reg_get32(ngep, NGE_MINTR_SRC);
17896f3e57acSmx205022 		nge_reg_put32(ngep, NGE_MINTR_SRC, mintr_src.src_val);
17906f3e57acSmx205022 		nge_wake_factotum(ngep);
17916f3e57acSmx205022 	}
17926f3e57acSmx205022 }
17936f3e57acSmx205022 
17946f3e57acSmx205022 /*
17956f3e57acSmx205022  *	nge_chip_intr() -- handle chip interrupts
17966f3e57acSmx205022  */
17976f3e57acSmx205022 /* ARGSUSED */
17986f3e57acSmx205022 uint_t
nge_chip_intr(caddr_t arg1,caddr_t arg2)17996f3e57acSmx205022 nge_chip_intr(caddr_t arg1, caddr_t arg2)
18006f3e57acSmx205022 {
18016f3e57acSmx205022 	nge_t *ngep = (nge_t *)arg1;
18026f3e57acSmx205022 	nge_intr_src intr_src;
18036f3e57acSmx205022 	nge_intr_mask intr_mask;
18046f3e57acSmx205022 
18056f3e57acSmx205022 	mutex_enter(ngep->genlock);
18066f3e57acSmx205022 
18072d58516dSmx205022 	if (ngep->suspended) {
18082d58516dSmx205022 		mutex_exit(ngep->genlock);
18092d58516dSmx205022 		return (DDI_INTR_UNCLAIMED);
18102d58516dSmx205022 	}
18112d58516dSmx205022 
18126f3e57acSmx205022 	/*
18136f3e57acSmx205022 	 * Check whether chip's says it's asserting #INTA;
18146f3e57acSmx205022 	 * if not, don't process or claim the interrupt.
18156f3e57acSmx205022 	 */
18166f3e57acSmx205022 	intr_src.intr_val = nge_reg_get32(ngep, NGE_INTR_SRC);
18176f3e57acSmx205022 	if (intr_src.intr_val == 0) {
18186f3e57acSmx205022 		mutex_exit(ngep->genlock);
18196f3e57acSmx205022 		return (DDI_INTR_UNCLAIMED);
18206f3e57acSmx205022 	}
18216f3e57acSmx205022 	/*
18226f3e57acSmx205022 	 * Ack the interrupt
18236f3e57acSmx205022 	 */
18246f3e57acSmx205022 	nge_reg_put32(ngep, NGE_INTR_SRC, intr_src.intr_val);
18256f3e57acSmx205022 
18266f3e57acSmx205022 	if (ngep->nge_chip_state != NGE_CHIP_RUNNING) {
18276f3e57acSmx205022 		mutex_exit(ngep->genlock);
18286f3e57acSmx205022 		return (DDI_INTR_CLAIMED);
18296f3e57acSmx205022 	}
18306f3e57acSmx205022 	nge_intr_handle(ngep, &intr_src);
18316f3e57acSmx205022 	if (ngep->poll && !ngep->ch_intr_mode) {
18326f3e57acSmx205022 		intr_mask.mask_val = nge_reg_get32(ngep, NGE_INTR_MASK);
18336f3e57acSmx205022 		intr_mask.mask_bits.stint = NGE_SET;
183402d51d0dSjj146644 		intr_mask.mask_bits.rcint = NGE_CLEAR;
18356f3e57acSmx205022 		nge_reg_put32(ngep, NGE_INTR_MASK, intr_mask.mask_val);
18366f3e57acSmx205022 		ngep->ch_intr_mode = B_TRUE;
18376f3e57acSmx205022 	} else if ((ngep->ch_intr_mode) && (!ngep->poll)) {
18386f3e57acSmx205022 		nge_reg_put32(ngep, NGE_INTR_MASK, ngep->intr_masks);
18396f3e57acSmx205022 		ngep->ch_intr_mode = B_FALSE;
18406f3e57acSmx205022 	}
18416f3e57acSmx205022 	mutex_exit(ngep->genlock);
18426f3e57acSmx205022 	return (DDI_INTR_CLAIMED);
18436f3e57acSmx205022 }
18446f3e57acSmx205022 
18456f3e57acSmx205022 static enum ioc_reply
nge_pp_ioctl(nge_t * ngep,int cmd,mblk_t * mp,struct iocblk * iocp)18466f3e57acSmx205022 nge_pp_ioctl(nge_t *ngep, int cmd, mblk_t *mp, struct iocblk *iocp)
18476f3e57acSmx205022 {
18486f3e57acSmx205022 	int err;
18496f3e57acSmx205022 	uint64_t sizemask;
18506f3e57acSmx205022 	uint64_t mem_va;
18516f3e57acSmx205022 	uint64_t maxoff;
18526f3e57acSmx205022 	boolean_t peek;
18536f3e57acSmx205022 	nge_peekpoke_t *ppd;
18546f3e57acSmx205022 	int (*ppfn)(nge_t *ngep, nge_peekpoke_t *ppd);
18556f3e57acSmx205022 
18566f3e57acSmx205022 	switch (cmd) {
18576f3e57acSmx205022 	default:
18586f3e57acSmx205022 		return (IOC_INVAL);
18596f3e57acSmx205022 
18606f3e57acSmx205022 	case NGE_PEEK:
18616f3e57acSmx205022 		peek = B_TRUE;
18626f3e57acSmx205022 		break;
18636f3e57acSmx205022 
18646f3e57acSmx205022 	case NGE_POKE:
18656f3e57acSmx205022 		peek = B_FALSE;
18666f3e57acSmx205022 		break;
18676f3e57acSmx205022 	}
18686f3e57acSmx205022 
18696f3e57acSmx205022 	/*
18706f3e57acSmx205022 	 * Validate format of ioctl
18716f3e57acSmx205022 	 */
18726f3e57acSmx205022 	if (iocp->ioc_count != sizeof (nge_peekpoke_t))
18736f3e57acSmx205022 		return (IOC_INVAL);
18746f3e57acSmx205022 	if (mp->b_cont == NULL)
18756f3e57acSmx205022 		return (IOC_INVAL);
18766f3e57acSmx205022 	ppd = (nge_peekpoke_t *)mp->b_cont->b_rptr;
18776f3e57acSmx205022 
18786f3e57acSmx205022 	/*
18796f3e57acSmx205022 	 * Validate request parameters
18806f3e57acSmx205022 	 */
18816f3e57acSmx205022 	switch (ppd->pp_acc_space) {
18826f3e57acSmx205022 	default:
18836f3e57acSmx205022 		return (IOC_INVAL);
18846f3e57acSmx205022 
18856f3e57acSmx205022 	case NGE_PP_SPACE_CFG:
18866f3e57acSmx205022 		/*
18876f3e57acSmx205022 		 * Config space
18886f3e57acSmx205022 		 */
18896f3e57acSmx205022 		sizemask = 8|4|2|1;
18906f3e57acSmx205022 		mem_va = 0;
18916f3e57acSmx205022 		maxoff = PCI_CONF_HDR_SIZE;
18926f3e57acSmx205022 		ppfn = peek ? nge_chip_peek_cfg : nge_chip_poke_cfg;
18936f3e57acSmx205022 		break;
18946f3e57acSmx205022 
18956f3e57acSmx205022 	case NGE_PP_SPACE_REG:
18966f3e57acSmx205022 		/*
18976f3e57acSmx205022 		 * Memory-mapped I/O space
18986f3e57acSmx205022 		 */
18996f3e57acSmx205022 		sizemask = 8|4|2|1;
19006f3e57acSmx205022 		mem_va = 0;
19016f3e57acSmx205022 		maxoff = NGE_REG_SIZE;
19026f3e57acSmx205022 		ppfn = peek ? nge_chip_peek_reg : nge_chip_poke_reg;
19036f3e57acSmx205022 		break;
19046f3e57acSmx205022 
19056f3e57acSmx205022 	case NGE_PP_SPACE_MII:
19066f3e57acSmx205022 		sizemask = 4|2|1;
19076f3e57acSmx205022 		mem_va = 0;
19086f3e57acSmx205022 		maxoff = NGE_MII_SIZE;
19096f3e57acSmx205022 		ppfn = peek ? nge_chip_peek_mii : nge_chip_poke_mii;
19106f3e57acSmx205022 		break;
19116f3e57acSmx205022 
19126f3e57acSmx205022 	case NGE_PP_SPACE_SEEPROM:
19136f3e57acSmx205022 		sizemask = 4|2|1;
19146f3e57acSmx205022 		mem_va = 0;
19156f3e57acSmx205022 		maxoff = NGE_SEEROM_SIZE;
19166f3e57acSmx205022 		ppfn = peek ? nge_chip_peek_seeprom : nge_chip_poke_seeprom;
19176f3e57acSmx205022 		break;
19186f3e57acSmx205022 	}
19196f3e57acSmx205022 
19206f3e57acSmx205022 	switch (ppd->pp_acc_size) {
19216f3e57acSmx205022 	default:
19226f3e57acSmx205022 		return (IOC_INVAL);
19236f3e57acSmx205022 
19246f3e57acSmx205022 	case 8:
19256f3e57acSmx205022 	case 4:
19266f3e57acSmx205022 	case 2:
19276f3e57acSmx205022 	case 1:
19286f3e57acSmx205022 		if ((ppd->pp_acc_size & sizemask) == 0)
19296f3e57acSmx205022 			return (IOC_INVAL);
19306f3e57acSmx205022 		break;
19316f3e57acSmx205022 	}
19326f3e57acSmx205022 
19336f3e57acSmx205022 	if ((ppd->pp_acc_offset % ppd->pp_acc_size) != 0)
19346f3e57acSmx205022 		return (IOC_INVAL);
19356f3e57acSmx205022 
19366f3e57acSmx205022 	if (ppd->pp_acc_offset >= maxoff)
19376f3e57acSmx205022 		return (IOC_INVAL);
19386f3e57acSmx205022 
19396f3e57acSmx205022 	if (ppd->pp_acc_offset+ppd->pp_acc_size > maxoff)
19406f3e57acSmx205022 		return (IOC_INVAL);
19416f3e57acSmx205022 
19426f3e57acSmx205022 	/*
19436f3e57acSmx205022 	 * All OK - go do it!
19446f3e57acSmx205022 	 */
19456f3e57acSmx205022 	ppd->pp_acc_offset += mem_va;
19466f3e57acSmx205022 	if (ppfn)
19476f3e57acSmx205022 		err = (*ppfn)(ngep, ppd);
19486f3e57acSmx205022 	if (err != DDI_SUCCESS)
19496f3e57acSmx205022 		return (IOC_INVAL);
19506f3e57acSmx205022 	return (peek ? IOC_REPLY : IOC_ACK);
19516f3e57acSmx205022 }
19526f3e57acSmx205022 
19536f3e57acSmx205022 static enum ioc_reply nge_diag_ioctl(nge_t *ngep, int cmd, mblk_t *mp,
19546f3e57acSmx205022 					struct iocblk *iocp);
19556f3e57acSmx205022 #pragma	no_inline(nge_diag_ioctl)
19566f3e57acSmx205022 
19576f3e57acSmx205022 static enum ioc_reply
nge_diag_ioctl(nge_t * ngep,int cmd,mblk_t * mp,struct iocblk * iocp)19586f3e57acSmx205022 nge_diag_ioctl(nge_t *ngep, int cmd, mblk_t *mp, struct iocblk *iocp)
19596f3e57acSmx205022 {
19606f3e57acSmx205022 	ASSERT(mutex_owned(ngep->genlock));
19616f3e57acSmx205022 
19626f3e57acSmx205022 	switch (cmd) {
19636f3e57acSmx205022 	default:
19646f3e57acSmx205022 		nge_error(ngep, "nge_diag_ioctl: invalid cmd 0x%x", cmd);
19656f3e57acSmx205022 		return (IOC_INVAL);
19666f3e57acSmx205022 
19676f3e57acSmx205022 	case NGE_DIAG:
19686f3e57acSmx205022 		return (IOC_ACK);
19696f3e57acSmx205022 
19706f3e57acSmx205022 	case NGE_PEEK:
19716f3e57acSmx205022 	case NGE_POKE:
19726f3e57acSmx205022 		return (nge_pp_ioctl(ngep, cmd, mp, iocp));
19736f3e57acSmx205022 
19746f3e57acSmx205022 	case NGE_PHY_RESET:
19756f3e57acSmx205022 		return (IOC_RESTART_ACK);
19766f3e57acSmx205022 
19776f3e57acSmx205022 	case NGE_SOFT_RESET:
19786f3e57acSmx205022 	case NGE_HARD_RESET:
19796f3e57acSmx205022 		return (IOC_ACK);
19806f3e57acSmx205022 	}
19816f3e57acSmx205022 
19826f3e57acSmx205022 	/* NOTREACHED */
19836f3e57acSmx205022 }
19846f3e57acSmx205022 
19856f3e57acSmx205022 enum ioc_reply
nge_chip_ioctl(nge_t * ngep,mblk_t * mp,struct iocblk * iocp)19866f3e57acSmx205022 nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp)
19876f3e57acSmx205022 {
19886f3e57acSmx205022 	int cmd;
19896f3e57acSmx205022 
19906f3e57acSmx205022 	ASSERT(mutex_owned(ngep->genlock));
19916f3e57acSmx205022 
19926f3e57acSmx205022 	cmd = iocp->ioc_cmd;
19936f3e57acSmx205022 
19946f3e57acSmx205022 	switch (cmd) {
19956f3e57acSmx205022 	default:
19966f3e57acSmx205022 		return (IOC_INVAL);
19976f3e57acSmx205022 
19986f3e57acSmx205022 	case NGE_DIAG:
19996f3e57acSmx205022 	case NGE_PEEK:
20006f3e57acSmx205022 	case NGE_POKE:
20016f3e57acSmx205022 	case NGE_PHY_RESET:
20026f3e57acSmx205022 	case NGE_SOFT_RESET:
20036f3e57acSmx205022 	case NGE_HARD_RESET:
20046f3e57acSmx205022 #if	NGE_DEBUGGING
20056f3e57acSmx205022 		return (nge_diag_ioctl(ngep, cmd, mp, iocp));
20066f3e57acSmx205022 #else
20076f3e57acSmx205022 		return (IOC_INVAL);
20086f3e57acSmx205022 #endif
20096f3e57acSmx205022 
20106f3e57acSmx205022 	case NGE_MII_READ:
20116f3e57acSmx205022 	case NGE_MII_WRITE:
20126f3e57acSmx205022 		return (IOC_INVAL);
20136f3e57acSmx205022 
20146f3e57acSmx205022 #if	NGE_SEE_IO32
20156f3e57acSmx205022 	case NGE_SEE_READ:
20166f3e57acSmx205022 	case NGE_SEE_WRITE:
20176f3e57acSmx205022 		return (IOC_INVAL);
20186f3e57acSmx205022 #endif
20196f3e57acSmx205022 
20206f3e57acSmx205022 #if	NGE_FLASH_IO32
20216f3e57acSmx205022 	case NGE_FLASH_READ:
20226f3e57acSmx205022 	case NGE_FLASH_WRITE:
20236f3e57acSmx205022 		return (IOC_INVAL);
20246f3e57acSmx205022 #endif
20256f3e57acSmx205022 	}
20266f3e57acSmx205022 }
2027