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 ®, 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 ®, 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*)®, 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, ®, 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), ®, 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, ®, 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, ®, 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, ®, 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, ®, 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 ®, 4); 686 reg.rx_flowctl = enable; 687 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port), 688 ®, 4); 689 690 return (0); 691 } 692