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