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 native_t 232 unm_niu_enable_gbe_port(struct unm_adapter_s *adapter) 233 { 234 unm_niu_gb_mac_config_0_t mac_cfg0; 235 unm_niu_gb_mac_config_1_t mac_cfg1; 236 unm_niu_gb_mii_mgmt_config_t mii_cfg; 237 native_t port = adapter->physical_port; 238 int zero = 0; 239 int one = 1; 240 u32 port_mode = 0; 241 242 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) { 243 return (-1); 244 } 245 246 if (adapter->link_speed != MBPS_10 && 247 adapter->link_speed != MBPS_100 && 248 adapter->link_speed != MBPS_1000) { 249 250 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 251 /* 252 * Do NOT fail this call because the cable is unplugged. 253 * Updated when the link comes up... 254 */ 255 adapter->link_speed = MBPS_1000; 256 } else { 257 return (-1); 258 } 259 } 260 261 port_mode = adapter->unm_nic_pci_read_normalize(adapter, 262 UNM_PORT_MODE_ADDR); 263 if (port_mode == UNM_PORT_MODE_802_3_AP) { 264 *(unm_crbword_t *)&mac_cfg0 = 0x0000003f; 265 *(unm_crbword_t *)&mac_cfg1 = 0x0000f2df; 266 unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_0(port), &mac_cfg0, 267 adapter); 268 unm_crb_write_adapter(UNM_NIU_AP_MAC_CONFIG_1(port), &mac_cfg1, 269 adapter); 270 } else { 271 *(unm_crbword_t *)&mac_cfg0 = 0; 272 mac_cfg0.soft_reset = 1; 273 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 274 adapter); 275 276 *(unm_crbword_t *)&mac_cfg0 = 0; 277 mac_cfg0.tx_enable = 1; 278 mac_cfg0.rx_enable = 1; 279 mac_cfg0.rx_flowctl = 0; 280 mac_cfg0.tx_reset_pb = 1; 281 mac_cfg0.rx_reset_pb = 1; 282 mac_cfg0.tx_reset_mac = 1; 283 mac_cfg0.rx_reset_mac = 1; 284 285 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 286 adapter); 287 288 *(unm_crbword_t *)&mac_cfg1 = 0; 289 mac_cfg1.preamblelen = 0xf; 290 mac_cfg1.duplex = 1; 291 mac_cfg1.crc_enable = 1; 292 mac_cfg1.padshort = 1; 293 mac_cfg1.checklength = 1; 294 mac_cfg1.hugeframes = 1; 295 296 switch (adapter->link_speed) { 297 case MBPS_10: 298 case MBPS_100: /* Fall Through */ 299 mac_cfg1.intfmode = 1; 300 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_1 301 (port), &mac_cfg1, adapter); 302 303 /* set mii mode */ 304 unm_crb_write_adapter( 305 UNM_NIU_GB0_GMII_MODE+(port<<3), 306 &zero, adapter); 307 unm_crb_write_adapter( 308 UNM_NIU_GB0_MII_MODE+(port<< 3), 309 &one, adapter); 310 break; 311 312 case MBPS_1000: 313 mac_cfg1.intfmode = 2; 314 unm_crb_write_adapter( 315 UNM_NIU_GB_MAC_CONFIG_1(port), 316 &mac_cfg1, adapter); 317 318 /* set gmii mode */ 319 unm_crb_write_adapter( 320 UNM_NIU_GB0_MII_MODE+(port << 3), 321 &zero, adapter); 322 unm_crb_write_adapter( 323 UNM_NIU_GB0_GMII_MODE+(port << 3), 324 &one, adapter); 325 break; 326 327 default: 328 /* Will not happen */ 329 break; 330 } 331 332 *(unm_crbword_t *)&mii_cfg = 0; 333 mii_cfg.clockselect = 7; 334 unm_crb_write_adapter(UNM_NIU_GB_MII_MGMT_CONFIG(port), 335 &mii_cfg, adapter); 336 337 *(unm_crbword_t *)&mac_cfg0 = 0; 338 mac_cfg0.tx_enable = 1; 339 mac_cfg0.rx_enable = 1; 340 mac_cfg0.tx_flowctl = 0; 341 mac_cfg0.rx_flowctl = 0; 342 unm_crb_write_adapter(UNM_NIU_GB_MAC_CONFIG_0(port), 343 &mac_cfg0, adapter); 344 } 345 346 return (0); 347 } 348 349 /* Disable a GbE interface */ 350 native_t 351 unm_niu_disable_gbe_port(struct unm_adapter_s *adapter) 352 { 353 native_t port = adapter->physical_port; 354 unm_niu_gb_mac_config_0_t mac_cfg0; 355 356 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) 357 return (-1); 358 359 *(unm_crbword_t *)&mac_cfg0 = 0; 360 mac_cfg0.soft_reset = 1; 361 362 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 363 adapter->unm_nic_hw_write_wx(adapter, 364 UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 0); 365 else 366 adapter->unm_nic_hw_write_wx(adapter, 367 UNM_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4); 368 return (0); 369 } 370 371 /* Disable an XG interface */ 372 native_t 373 unm_niu_disable_xg_port(struct unm_adapter_s *adapter) 374 { 375 native_t port = adapter->physical_port; 376 unm_niu_xg_mac_config_0_t mac_cfg; 377 378 *(unm_crbword_t *)&mac_cfg = 0; 379 mac_cfg.soft_reset = 1; 380 381 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 382 if (port != 0) 383 return (-1); 384 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0, 385 &mac_cfg, 4); 386 } else { 387 if ((port < 0) || (port >= UNM_NIU_MAX_XG_PORTS)) 388 return (-1); 389 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 + 390 (port * 0x10000), &mac_cfg, 4); 391 } 392 return (0); 393 } 394 395 396 /* Set promiscuous mode for a GbE interface */ 397 native_t 398 unm_niu_set_promiscuous_mode(struct unm_adapter_s *adapter, 399 unm_niu_prom_mode_t mode) 400 { 401 native_t port = adapter->physical_port; 402 unm_niu_gb_drop_crc_t reg; 403 unm_niu_gb_mac_config_0_t mac_cfg; 404 unm_crbword_t data; 405 int cnt = 0, ret = 0; 406 ulong_t val; 407 408 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) 409 return (-1); 410 411 /* Turn off mac */ 412 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port), 413 &mac_cfg, 4); 414 mac_cfg.rx_enable = 0; 415 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port), 416 &mac_cfg, 4); 417 418 /* wait until mac is drained by sre */ 419 /* Port 0 rx fifo bit 5 */ 420 val = (0x20 << port); 421 adapter->unm_crb_writelit_adapter(adapter, UNM_NIU_FRAME_COUNT_SELECT, 422 val); 423 424 do { 425 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_FRAME_COUNT, 426 &val, 4); 427 cnt++; 428 if (cnt > 2000) { 429 ret = -1; 430 break; 431 } 432 drv_usecwait(10); 433 } while (val); 434 435 /* now set promiscuous mode */ 436 if (ret != -1) { 437 if (mode == UNM_NIU_PROMISCOUS_MODE) 438 data = 0; 439 else 440 data = 1; 441 442 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR, 443 ®, 4); 444 switch (port) { 445 case 0: 446 reg.drop_gb0 = data; 447 break; 448 case 1: 449 reg.drop_gb1 = data; 450 break; 451 case 2: 452 reg.drop_gb2 = data; 453 break; 454 case 3: 455 reg.drop_gb3 = data; 456 break; 457 default: 458 ret = -1; 459 break; 460 } 461 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_DROP_WRONGADDR, 462 ®, 4); 463 } 464 465 /* turn the mac on back */ 466 mac_cfg.rx_enable = 1; 467 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port), 468 &mac_cfg, 4); 469 470 return (ret); 471 } 472 473 /* 474 * Set the MAC address for an XG port 475 * Note that the passed-in value must already be in network byte order. 476 */ 477 int 478 unm_niu_xg_macaddr_set(struct unm_adapter_s *adapter, 479 unm_ethernet_macaddr_t addr) 480 { 481 int phy = adapter->physical_port; 482 unm_crbword_t temp = 0; 483 u32 port_mode = 0; 484 485 if ((phy < 0) || (phy > 3)) 486 return (-1); 487 488 switch (phy) { 489 case 0: 490 (void) memcpy(&temp, addr, 2); 491 temp <<= 16; 492 port_mode = adapter->unm_nic_pci_read_normalize(adapter, 493 UNM_PORT_MODE_ADDR); 494 if (port_mode == UNM_PORT_MODE_802_3_AP) { 495 adapter->unm_nic_hw_write_wx(adapter, 496 UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4); 497 temp = 0; 498 (void) memcpy(&temp, ((__uint8_t *)addr) + 2, 499 sizeof (unm_crbword_t)); 500 adapter->unm_nic_hw_write_wx(adapter, 501 UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4); 502 } else { 503 adapter->unm_nic_hw_write_wx(adapter, 504 UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4); 505 temp = 0; 506 (void) memcpy(&temp, ((__uint8_t *)addr) + 2, 507 sizeof (unm_crbword_t)); 508 adapter->unm_nic_hw_write_wx(adapter, 509 UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4); 510 } 511 break; 512 513 case 1: 514 (void) memcpy(&temp, addr, 2); 515 temp <<= 16; 516 port_mode = adapter->unm_nic_pci_read_normalize(adapter, 517 UNM_PORT_MODE_ADDR); 518 if (port_mode == UNM_PORT_MODE_802_3_AP) { 519 adapter->unm_nic_hw_write_wx(adapter, 520 UNM_NIU_AP_STATION_ADDR_1(phy), &temp, 4); 521 temp = 0; 522 (void) memcpy(&temp, ((__uint8_t *)addr) + 2, 523 sizeof (unm_crbword_t)); 524 adapter->unm_nic_hw_write_wx(adapter, 525 UNM_NIU_AP_STATION_ADDR_0(phy), &temp, 4); 526 } else { 527 adapter->unm_nic_hw_write_wx(adapter, 528 UNM_NIU_XGE_STATION_ADDR_0_1, &temp, 4); 529 temp = 0; 530 (void) memcpy(&temp, ((__uint8_t *)addr) + 2, 531 sizeof (unm_crbword_t)); 532 adapter->unm_nic_hw_write_wx(adapter, 533 UNM_NIU_XGE_STATION_ADDR_0_HI, &temp, 4); 534 } 535 break; 536 537 default: 538 cmn_err(CE_WARN, "Unknown port %d\n", phy); 539 return (DDI_FAILURE); 540 } 541 542 return (0); 543 } 544 545 native_t 546 unm_niu_xg_set_promiscuous_mode(struct unm_adapter_s *adapter, 547 unm_niu_prom_mode_t mode) 548 { 549 long reg; 550 unm_niu_xg_mac_config_0_t mac_cfg; 551 native_t port = adapter->physical_port; 552 int cnt = 0; 553 int result = 0; 554 u32 port_mode = 0; 555 556 if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS)) 557 return (-1); 558 559 port_mode = adapter->unm_nic_pci_read_normalize(adapter, 560 UNM_PORT_MODE_ADDR); 561 562 if (port_mode == UNM_PORT_MODE_802_3_AP) { 563 reg = 0; 564 adapter->unm_nic_hw_write_wx(adapter, 565 UNM_NIU_GB_DROP_WRONGADDR, (void*)®, 4); 566 } else { 567 /* Turn off mac */ 568 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XGE_CONFIG_0 + 569 (0x10000 * port), &mac_cfg, 4); 570 mac_cfg.rx_enable = 0; 571 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 + 572 (0x10000 * port), &mac_cfg, 4); 573 574 /* wait until mac is drained by sre */ 575 if ((adapter->ahw.boardcfg.board_type != 576 UNM_BRDTYPE_P2_SB31_10G_IMEZ) && 577 (adapter->ahw.boardcfg.board_type != 578 UNM_BRDTYPE_P2_SB31_10G_HMEZ)) { 579 /* single port case bit 9 */ 580 reg = 0x0200; 581 adapter->unm_crb_writelit_adapter(adapter, 582 UNM_NIU_FRAME_COUNT_SELECT, reg); 583 } else { 584 /* Port 0 rx fifo bit 5 */ 585 reg = (0x20 << port); 586 adapter->unm_crb_writelit_adapter(adapter, 587 UNM_NIU_FRAME_COUNT_SELECT, reg); 588 } 589 do { 590 adapter->unm_nic_hw_read_wx(adapter, 591 UNM_NIU_FRAME_COUNT, ®, 4); 592 cnt++; 593 if (cnt > 2000) { 594 result = -1; 595 break; 596 } 597 drv_usecwait(10); 598 } while (reg); 599 600 /* now set promiscuous mode */ 601 if (result != -1) { 602 adapter->unm_nic_hw_read_wx(adapter, 603 UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4); 604 if (mode == UNM_NIU_PROMISCOUS_MODE) { 605 reg = (reg | 0x2000UL); 606 } else { /* FIXME use the correct mode value here */ 607 reg = (reg & ~0x2000UL); 608 } 609 adapter->unm_crb_writelit_adapter(adapter, 610 UNM_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); 611 } 612 613 /* turn the mac back on */ 614 mac_cfg.rx_enable = 1; 615 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XGE_CONFIG_0 + 616 (0x10000 * port), &mac_cfg, 4); 617 } 618 619 return (result); 620 } 621 622 int 623 unm_niu_xg_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable) 624 { 625 int port = adapter->physical_port; 626 unm_niu_xg_pause_ctl_t reg; 627 628 if ((port < 0) || (port > UNM_NIU_MAX_XG_PORTS)) 629 return (-1); 630 631 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_XG_PAUSE_CTL, ®, 4); 632 if (port == 0) 633 reg.xg0_mask = !enable; 634 else 635 reg.xg1_mask = !enable; 636 637 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_XG_PAUSE_CTL, ®, 4); 638 639 return (0); 640 } 641 642 int 643 unm_niu_gbe_set_tx_flow_ctl(struct unm_adapter_s *adapter, int enable) 644 { 645 int port = adapter->physical_port; 646 unm_niu_gb_pause_ctl_t reg; 647 648 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) 649 return (-1); 650 651 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_PAUSE_CTL, ®, 4); 652 switch (port) { 653 case (0): 654 reg.gb0_mask = !enable; 655 break; 656 case (1): 657 reg.gb1_mask = !enable; 658 break; 659 case (2): 660 reg.gb2_mask = !enable; 661 break; 662 case (3): 663 default: 664 reg.gb3_mask = !enable; 665 break; 666 } 667 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_PAUSE_CTL, ®, 4); 668 669 return (0); 670 } 671 672 int 673 unm_niu_gbe_set_rx_flow_ctl(struct unm_adapter_s *adapter, int enable) 674 { 675 int port = adapter->physical_port; 676 unm_niu_gb_mac_config_0_t reg; 677 678 if ((port < 0) || (port > UNM_NIU_MAX_GBE_PORTS)) 679 return (-1); 680 681 adapter->unm_nic_hw_read_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port), 682 ®, 4); 683 reg.rx_flowctl = enable; 684 adapter->unm_nic_hw_write_wx(adapter, UNM_NIU_GB_MAC_CONFIG_0(port), 685 ®, 4); 686 687 return (0); 688 } 689