Home | History | Annotate | Download | only in ntxn
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 NetXen, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include <sys/types.h>
     28 #include <sys/conf.h>
     29 #include <sys/debug.h>
     30 #include <sys/stropts.h>
     31 #include <sys/stream.h>
     32 #include <sys/strlog.h>
     33 #include <sys/kmem.h>
     34 #include <sys/stat.h>
     35 #include <sys/kstat.h>
     36 #include <sys/vtrace.h>
     37 #include <sys/dlpi.h>
     38 #include <sys/strsun.h>
     39 #include <sys/ethernet.h>
     40 #include <sys/modctl.h>
     41 #include <sys/errno.h>
     42 #include <sys/dditypes.h>
     43 #include <sys/ddi.h>
     44 #include <sys/sunddi.h>
     45 #include <sys/sysmacros.h>
     46 
     47 #include <sys/pci.h>
     48 
     49 #include "unm_inc.h"
     50 #include "unm_nic.h"
     51 
     52 static long phy_lock_timeout = 100000000;
     53 
     54 static int phy_lock(struct unm_adapter_s *adapter)
     55 {
     56 	u32	done = 0;
     57 	int	timeout = 0;
     58 
     59 	while (!done) {
     60 		/* acquire semaphore3 from PCI HW block */
     61 		adapter->unm_nic_pci_read_immediate(adapter,
     62 		    UNM_PCIE_REG(PCIE_SEM3_LOCK), &done);
     63 		if (done == 1)
     64 			break;
     65 		if (timeout >= phy_lock_timeout)
     66 			return (-1);
     67 		timeout++;
     68 	}
     69 
     70 	adapter->unm_crb_writelit_adapter(adapter, UNM_PHY_LOCK_ID,
     71 	    PHY_LOCK_DRIVER);
     72 	return (0);
     73 }
     74 
     75 static void
     76 phy_unlock(struct unm_adapter_s *adapter)
     77 {
     78 	u32	val;
     79 
     80 	/* release semaphore3 */
     81 	adapter->unm_nic_pci_read_immediate(adapter,
     82 	    UNM_PCIE_REG(PCIE_SEM3_UNLOCK), &val);
     83 }
     84 
     85 /*
     86  * unm_niu_gbe_phy_read - read a register from the GbE PHY via
     87  * mii management interface.
     88  *
     89  * Note: The MII management interface goes through port 0.
     90  *	   Individual phys are addressed as follows:
     91  *	   [15:8]  phy id
     92  *	   [7:0]   register number
     93  *
     94  * Returns:  0 success
     95  *	  -1 error
     96  *
     97  */
     98 long
     99 unm_niu_gbe_phy_read(struct unm_adapter_s *adapter, long reg,
    100     unm_crbword_t *readval)
    101 {
    102 	long phy = adapter->physical_port;
    103 	unm_niu_gb_mii_mgmt_address_t address;
    104 	unm_niu_gb_mii_mgmt_command_t command;
    105 	unm_niu_gb_mii_mgmt_indicators_t status;
    106 
    107 	long timeout = 0;
    108 	long result = 0;
    109 	long restore = 0;
    110 	unm_niu_gb_mac_config_0_t mac_cfg0;
    111 
    112 	if (phy_lock(adapter) != 0)
    113 		return (-1);
    114 
    115 	/*
    116 	 * MII mgmt all goes through port 0 MAC interface, so it cannot be
    117 	 * in reset
    118 	 */
    119 	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(0),
    120 	    &mac_cfg0, 4);
    121 	if (mac_cfg0.soft_reset) {
    122 		unm_niu_gb_mac_config_0_t temp;
    123 		*(unm_crbword_t *)&temp = 0;
    124 		temp.tx_reset_pb = 1;
    125 		temp.rx_reset_pb = 1;
    126 		temp.tx_reset_mac = 1;
    127 		temp.rx_reset_mac = 1;
    128 		adapter->unm_nic_hw_write_wx(adapter,
    129 		    UNM_NIU_GB_MAC_CONFIG_0(0), &temp, 4);
    130 		restore = 1;
    131 	}
    132 
    133 	*(unm_crbword_t *)&address = 0;
    134 	address.reg_addr = (unm_crbword_t)reg;
    135 	address.phy_addr = (unm_crbword_t)phy;
    136 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_ADDR(0),
    137 	    &address, 4);
    138 
    139 	*(unm_crbword_t *)&command = 0;	/* turn off any prior activity */
    140 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_COMMAND(0),
    141 	    &command, 4);
    142 
    143 	/* send read command */
    144 	command.read_cycle = 1;
    145 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MII_MGMT_COMMAND(0),
    146 	    &command, 4);
    147 
    148 	*(unm_crbword_t *)&status = 0;
    149 	do {
    150 		adapter->unm_nic_hw_read_wx(adapter,
    151 		    UNM_NIU_GB_MII_MGMT_INDICATE(0), &status, 4);
    152 		timeout++;
    153 	} while ((status.busy || status.notvalid) &&
    154 	    (timeout++ < UNM_NIU_PHY_WAITMAX));
    155 
    156 	if (timeout < UNM_NIU_PHY_WAITMAX) {
    157 		adapter->unm_nic_hw_read_wx(adapter,
    158 		    UNM_NIU_GB_MII_MGMT_STATUS(0), readval, 4);
    159 		result = 0;
    160 	} else
    161 		result = -1;
    162 
    163 	if (restore)
    164 		adapter->unm_nic_hw_write_wx(adapter,
    165 		    UNM_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4);
    166 
    167 	phy_unlock(adapter);
    168 
    169 	return (result);
    170 }
    171 
    172 /*
    173  * Return the current station MAC address.
    174  * Note that the passed-in value must already be in network byte order.
    175  */
    176 int
    177 unm_niu_macaddr_get(struct unm_adapter_s *adapter, unsigned char *addr)
    178 {
    179 	__uint64_t result;
    180 	int phy = adapter->physical_port;
    181 
    182 	if (addr == NULL)
    183 		return (-1);
    184 	if ((phy < 0) || (phy > 3))
    185 		return (-1);
    186 
    187 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
    188 	if (adapter->curr_window != 0) {
    189 		adapter->unm_nic_pci_change_crbwindow(adapter, 0);
    190 	}
    191 
    192 	result = UNM_NIC_PCI_READ_32((void *)pci_base_offset(adapter,
    193 	    UNM_NIU_GB_STATION_ADDR_1(phy))) >> 16;
    194 	result |= ((uint64_t)UNM_NIC_PCI_READ_32((void *)pci_base_offset(
    195 	    adapter, UNM_NIU_GB_STATION_ADDR_0(phy)))) << 16;
    196 
    197 	(void) memcpy(addr, &result, sizeof (unm_ethernet_macaddr_t));
    198 
    199 	adapter->unm_nic_pci_change_crbwindow(adapter, 1);
    200 
    201 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
    202 
    203 	return (0);
    204 }
    205 
    206 /*
    207  * Set the station MAC address.
    208  * Note that the passed-in value must already be in network byte order.
    209  */
    210 int
    211 unm_niu_macaddr_set(struct unm_adapter_s *adapter, unm_ethernet_macaddr_t addr)
    212 {
    213 	unm_crbword_t temp = 0;
    214 	int phy = adapter->physical_port;
    215 
    216 	if ((phy < 0) || (phy > 3))
    217 		return (-1);
    218 
    219 	(void) memcpy(&temp, addr, 2);
    220 	temp <<= 16;
    221 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_STATION_ADDR_1(phy),
    222 	    &temp, 4);
    223 	temp = 0;
    224 	(void) memcpy(&temp, ((__uint8_t *)addr)+2, sizeof (unm_crbword_t));
    225 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_STATION_ADDR_0(phy),
    226 	    &temp, 4);
    227 	return (0);
    228 }
    229 
    230 /* Enable a GbE interface */
    231 /* ARGSUSED */
    232 native_t unm_niu_enable_gbe_port(struct unm_adapter_s *adapter,
    233 		unm_niu_gbe_ifmode_t mode_dont_care)
    234 {
    235 	unm_niu_gb_mac_config_0_t mac_cfg0;
    236 	unm_niu_gb_mac_config_1_t mac_cfg1;
    237 	unm_niu_gb_mii_mgmt_config_t mii_cfg;
    238 	native_t port = adapter->physical_port;
    239 	int zero = 0;
    240 	int one = 1;
    241 	u32 port_mode = 0;
    242 
    243 	mode_dont_care = 0;
    244 
    245 	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) {
    246 		return (-1);
    247 	}
    248 
    249 	if (adapter->link_speed != MBPS_10 &&
    250 	    adapter->link_speed != MBPS_100 &&
    251 	    adapter->link_speed != MBPS_1000) {
    252 
    253 		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
    254 /*
    255  * Do NOT fail this call because the cable is unplugged.
    256  * Updated when the link comes up...
    257  */
    258 		adapter->link_speed = MBPS_1000;
    259 		} else {
    260 			return (-1);
    261 		}
    262 	}
    263 
    264 	port_mode = adapter->unm_nic_pci_read_normalize(adapter,
    265 	    UNM_PORT_MODE_ADDR);
    266 	if (port_mode == UNM_PORT_MODE_802_3_AP) {
    267 		*(unm_crbword_t *)&mac_cfg0 = 0x0000003f;
    268 		*(unm_crbword_t *)&mac_cfg1 = 0x0000f2df;
    269 		unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_0(port), &mac_cfg0,
    270 		    adapter);
    271 		unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_1(port), &mac_cfg1,
    272 		    adapter);
    273 	} else {
    274 		*(unm_crbword_t *)&mac_cfg0 = 0;
    275 		mac_cfg0.soft_reset = 1;
    276 		unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0,
    277 		    adapter);
    278 
    279 		*(unm_crbword_t *)&mac_cfg0 = 0;
    280 		mac_cfg0.tx_enable = 1;
    281 		mac_cfg0.rx_enable = 1;
    282 		mac_cfg0.rx_flowctl = 0;
    283 		mac_cfg0.tx_reset_pb = 1;
    284 		mac_cfg0.rx_reset_pb = 1;
    285 		mac_cfg0.tx_reset_mac = 1;
    286 		mac_cfg0.rx_reset_mac = 1;
    287 
    288 		unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0,
    289 		    adapter);
    290 
    291 		*(unm_crbword_t *)&mac_cfg1 = 0;
    292 		mac_cfg1.preamblelen = 0xf;
    293 		mac_cfg1.duplex = 1;
    294 		mac_cfg1.crc_enable = 1;
    295 		mac_cfg1.padshort = 1;
    296 		mac_cfg1.checklength = 1;
    297 		mac_cfg1.hugeframes = 1;
    298 
    299 		switch (adapter->link_speed) {
    300 			case MBPS_10:
    301 			case MBPS_100: /* Fall Through */
    302 				mac_cfg1.intfmode = 1;
    303 				unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_1
    304 				    (port), &mac_cfg1, adapter);
    305 
    306 				/* set mii mode */
    307 				unm_crb_write_adapter(
    308 				    UNM_NIU_GB0_GMII_MODE+(port<<3),
    309 				    &zero, adapter);
    310 				unm_crb_write_adapter(
    311 				    UNM_NIU_GB0_MII_MODE+(port<< 3),
    312 				    &one, adapter);
    313 				break;
    314 
    315 			case MBPS_1000:
    316 				mac_cfg1.intfmode = 2;
    317 				unm_crb_write_adapter(
    318 				    UNM_NIU_GB_MAC_CONFIG_1(port),
    319 				    &mac_cfg1, adapter);
    320 
    321 				/* set gmii mode */
    322 				unm_crb_write_adapter(
    323 				    UNM_NIU_GB0_MII_MODE+(port << 3),
    324 				    &zero, adapter);
    325 				unm_crb_write_adapter(
    326 				    UNM_NIU_GB0_GMII_MODE+(port << 3),
    327 				    &one, adapter);
    328 				break;
    329 
    330 			default:
    331 				/* Will not happen */
    332 				break;
    333 		}
    334 
    335 		*(unm_crbword_t *)&mii_cfg = 0;
    336 		mii_cfg.clockselect = 7;
    337 		unm_crb_write_adapter(UNM_NIU_GB_MII_MGMT_CONFIG(port),
    338 		    &mii_cfg, adapter);
    339 
    340 		*(unm_crbword_t *)&mac_cfg0 = 0;
    341 		mac_cfg0.tx_enable = 1;
    342 		mac_cfg0.rx_enable = 1;
    343 		mac_cfg0.tx_flowctl = 0;
    344 		mac_cfg0.rx_flowctl = 0;
    345 		unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port),
    346 		    &mac_cfg0, adapter);
    347 	}
    348 
    349 	return (0);
    350 }
    351 
    352 /* Disable a GbE interface */
    353 native_t
    354 unm_niu_disable_gbe_port(struct unm_adapter_s *adapter)
    355 {
    356 	native_t			port = adapter->physical_port;
    357 	unm_niu_gb_mac_config_0_t	mac_cfg0;
    358 
    359 	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
    360 		return (-1);
    361 
    362 	*(unm_crbword_t *)&mac_cfg0 = 0;
    363 	mac_cfg0.soft_reset = 1;
    364 
    365 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
    366 		adapter->unm_nic_hw_write_wx(adapter,
    367 		    UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 0);
    368 	else
    369 		adapter->unm_nic_hw_write_wx(adapter,
    370 		    UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4);
    371 	return (0);
    372 }
    373 
    374 /* Disable an XG interface */
    375 native_t
    376 unm_niu_disable_xg_port(struct unm_adapter_s *adapter)
    377 {
    378 	native_t			port = adapter->physical_port;
    379 	unm_niu_xg_mac_config_0_t	mac_cfg;
    380 
    381 	*(unm_crbword_t *)&mac_cfg = 0;
    382 	mac_cfg.soft_reset = 1;
    383 
    384 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
    385 		if (port != 0)
    386 			return (-1);
    387 		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0,
    388 		    &mac_cfg, 4);
    389 	} else {
    390 		if ((port < 0) || (port >= UNM_NIU_MAX_XG_PORTS))
    391 			return (-1);
    392 		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
    393 		    (port * 0x10000), &mac_cfg, 4);
    394 	}
    395 	return (0);
    396 }
    397 
    398 
    399 /* Set promiscuous mode for a GbE interface */
    400 native_t
    401 unm_niu_set_promiscuous_mode(struct unm_adapter_s *adapter,
    402     unm_niu_prom_mode_t mode)
    403 {
    404 	native_t port = adapter->physical_port;
    405 	unm_niu_gb_drop_crc_t reg;
    406 	unm_niu_gb_mac_config_0_t mac_cfg;
    407 	unm_crbword_t data;
    408 	int cnt = 0, ret = 0;
    409 	ulong_t val;
    410 
    411 	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
    412 		return (-1);
    413 
    414 	/* Turn off mac */
    415 	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
    416 	    &mac_cfg, 4);
    417 	mac_cfg.rx_enable = 0;
    418 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
    419 	    &mac_cfg, 4);
    420 
    421 	/* wait until mac is drained by sre */
    422 	/* Port 0 rx fifo bit 5 */
    423 	val = (0x20 << port);
    424 	adapter->unm_crb_writelit_adapter(adapter, UNM_NIU_FRAME_COUNT_SELECT,
    425 	    val);
    426 
    427 	do {
    428 		adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_FRAME_COUNT,
    429 		    &val, 4);
    430 		cnt++;
    431 		if (cnt > 2000) {
    432 			ret = -1;
    433 			break;
    434 		}
    435 		drv_usecwait(10);
    436 	} while (val);
    437 
    438 	/* now set promiscuous mode */
    439 	if (ret != -1) {
    440 		if (mode == UNM_NIU_PROMISCOUS_MODE)
    441 			data = 0;
    442 		else
    443 			data = 1;
    444 
    445 		adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR,
    446 		    &reg, 4);
    447 		switch (port) {
    448 		case 0:
    449 			reg.drop_gb0 = data;
    450 			break;
    451 		case 1:
    452 			reg.drop_gb1 = data;
    453 			break;
    454 		case 2:
    455 			reg.drop_gb2 = data;
    456 			break;
    457 		case 3:
    458 			reg.drop_gb3 = data;
    459 			break;
    460 		default:
    461 			ret  = -1;
    462 			break;
    463 		}
    464 		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR,
    465 		    &reg, 4);
    466 	}
    467 
    468 	/* turn the mac on back */
    469 	mac_cfg.rx_enable = 1;
    470 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
    471 	    &mac_cfg, 4);
    472 
    473 	return (ret);
    474 }
    475 
    476 /*
    477  * Set the MAC address for an XG port
    478  * Note that the passed-in value must already be in network byte order.
    479  */
    480 int
    481 unm_niu_xg_macaddr_set(struct unm_adapter_s *adapter,
    482 		unm_ethernet_macaddr_t addr)
    483 {
    484 	int		phy = adapter->physical_port;
    485 	unm_crbword_t	temp = 0;
    486 	u32		port_mode = 0;
    487 
    488 	if ((phy < 0) || (phy > 3))
    489 		return (-1);
    490 
    491 	switch (phy) {
    492 	case 0:
    493 		(void) memcpy(&temp, addr, 2);
    494 		temp <<= 16;
    495 		port_mode = adapter->unm_nic_pci_read_normalize(adapter,
    496 		    UNM_PORT_MODE_ADDR);
    497 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
    498 			adapter->unm_nic_hw_write_wx(adapter,
    499 			    UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4);
    500 			temp = 0;
    501 			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
    502 			    sizeof (unm_crbword_t));
    503 			adapter->unm_nic_hw_write_wx(adapter,
    504 			    UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4);
    505 		} else {
    506 			adapter->unm_nic_hw_write_wx(adapter,
    507 			    UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4);
    508 			temp = 0;
    509 			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
    510 			    sizeof (unm_crbword_t));
    511 			adapter->unm_nic_hw_write_wx(adapter,
    512 			    UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4);
    513 		}
    514 		break;
    515 
    516 	case 1:
    517 		(void) memcpy(&temp, addr, 2);
    518 		temp <<= 16;
    519 		port_mode = adapter->unm_nic_pci_read_normalize(adapter,
    520 		    UNM_PORT_MODE_ADDR);
    521 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
    522 			adapter->unm_nic_hw_write_wx(adapter,
    523 			    UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4);
    524 			temp = 0;
    525 			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
    526 			    sizeof (unm_crbword_t));
    527 			adapter->unm_nic_hw_write_wx(adapter,
    528 			    UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4);
    529 		} else {
    530 			adapter->unm_nic_hw_write_wx(adapter,
    531 			    UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4);
    532 			temp = 0;
    533 			(void) memcpy(&temp, ((__uint8_t *)addr) + 2,
    534 			    sizeof (unm_crbword_t));
    535 			adapter->unm_nic_hw_write_wx(adapter,
    536 			    UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4);
    537 		}
    538 		break;
    539 
    540 	default:
    541 		cmn_err(CE_WARN, "Unknown port %d\n", phy);
    542 		return (DDI_FAILURE);
    543 	}
    544 
    545 	return (0);
    546 }
    547 
    548 native_t
    549 unm_niu_xg_set_promiscuous_mode(struct unm_adapter_s *adapter,
    550     unm_niu_prom_mode_t mode)
    551 {
    552 	long  reg;
    553 	unm_niu_xg_mac_config_0_t mac_cfg;
    554 	native_t port = adapter->physical_port;
    555 	int cnt = 0;
    556 	int result = 0;
    557 	u32 port_mode = 0;
    558 
    559 	if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS))
    560 		return (-1);
    561 
    562 	port_mode = adapter->unm_nic_pci_read_normalize(adapter,
    563 	    UNM_PORT_MODE_ADDR);
    564 
    565 	if (port_mode == UNM_PORT_MODE_802_3_AP) {
    566 		reg = 0;
    567 		adapter->unm_nic_hw_write_wx(adapter,
    568 		    UNM_NIU_GB_DROP_WRONGADDR, (void*)&reg, 4);
    569 	} else {
    570 		/* Turn off mac */
    571 		adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
    572 		    (0x10000 * port), &mac_cfg, 4);
    573 		mac_cfg.rx_enable = 0;
    574 		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
    575 		    (0x10000 * port), &mac_cfg, 4);
    576 
    577 		/* wait until mac is drained by sre */
    578 		if ((adapter->ahw.boardcfg.board_type !=
    579 		    UNM_BRDTYPE_P2_SB31_10G_IMEZ) &&
    580 		    (adapter->ahw.boardcfg.board_type !=
    581 		    UNM_BRDTYPE_P2_SB31_10G_HMEZ)) {
    582 			/* single port case bit 9 */
    583 			reg = 0x0200;
    584 			adapter->unm_crb_writelit_adapter(adapter,
    585 			    UNM_NIU_FRAME_COUNT_SELECT, reg);
    586 		} else {
    587 			/* Port 0 rx fifo bit 5 */
    588 			reg = (0x20 << port);
    589 			adapter->unm_crb_writelit_adapter(adapter,
    590 			    UNM_NIU_FRAME_COUNT_SELECT, reg);
    591 		}
    592 		do {
    593 			adapter->unm_nic_hw_read_wx(adapter,
    594 			    UNM_NIU_FRAME_COUNT, &reg, 4);
    595 			cnt++;
    596 			if (cnt > 2000) {
    597 				result = -1;
    598 				break;
    599 			}
    600 			drv_usecwait(10);
    601 		} while (reg);
    602 
    603 		/* now set promiscuous mode */
    604 		if (result != -1) {
    605 			adapter->unm_nic_hw_read_wx(adapter,
    606 			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4);
    607 			if (mode == UNM_NIU_PROMISCOUS_MODE) {
    608 				reg = (reg | 0x2000UL);
    609 			} else { /* FIXME  use the correct mode value here */
    610 				reg = (reg & ~0x2000UL);
    611 			}
    612 			adapter->unm_crb_writelit_adapter(adapter,
    613 			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
    614 		}
    615 
    616 		/* turn the mac back on */
    617 		mac_cfg.rx_enable = 1;
    618 		adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 +
    619 		    (0x10000 * port), &mac_cfg, 4);
    620 	}
    621 
    622 	return (result);
    623 }
    624 
    625 int
    626 unm_niu_xg_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable)
    627 {
    628 	int port = adapter->physical_port;
    629 	unm_niu_xg_pause_ctl_t reg;
    630 
    631 	if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS))
    632 		return (-1);
    633 
    634 	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XG_PAUSE_CTL, &reg, 4);
    635 	if (port == 0)
    636 		reg.xg0_mask = !enable;
    637 	else
    638 		reg.xg1_mask = !enable;
    639 
    640 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XG_PAUSE_CTL, &reg, 4);
    641 
    642 	return (0);
    643 }
    644 
    645 int
    646 unm_niu_gbe_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable)
    647 {
    648 	int port = adapter->physical_port;
    649 	unm_niu_gb_pause_ctl_t reg;
    650 
    651 	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
    652 		return (-1);
    653 
    654 	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_PAUSE_CTL, &reg, 4);
    655 	switch (port) {
    656 	case (0):
    657 		reg.gb0_mask = !enable;
    658 		break;
    659 	case (1):
    660 		reg.gb1_mask = !enable;
    661 		break;
    662 	case (2):
    663 		reg.gb2_mask = !enable;
    664 		break;
    665 	case (3):
    666 	default:
    667 		reg.gb3_mask = !enable;
    668 		break;
    669 	}
    670 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_PAUSE_CTL, &reg, 4);
    671 
    672 	return (0);
    673 }
    674 
    675 int
    676 unm_niu_gbe_set_rx_flow_ctl(struct unm_adapter_s *adapter, int enable)
    677 {
    678 	int port = adapter->physical_port;
    679 	unm_niu_gb_mac_config_0_t reg;
    680 
    681 	if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS))
    682 		return (-1);
    683 
    684 	adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
    685 	    &reg, 4);
    686 	reg.rx_flowctl = enable;
    687 	adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port),
    688 	    &reg, 4);
    689 
    690 	return (0);
    691 }
    692