1/* 2 * Copyright (C) 2003 - 2006 NetXen, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 18 * MA 02111-1307, USA. 19 * 20 * The full GNU General Public License is included in this distribution 21 * in the file called LICENSE. 22 * 23 * Contact Information: 24 * info@netxen.com 25 * NetXen, 26 * 3965 Freedom Circle, Fourth floor, 27 * Santa Clara, CA 95054 28 * 29 * 30 * Provides access to the Network Interface Unit h/w block. 31 * 32 */ 33 34#include "netxen_nic.h" 35 36#define NETXEN_GB_MAC_SOFT_RESET 0x80000000 37#define NETXEN_GB_MAC_RESET_PROT_BLK 0x000F0000 38#define NETXEN_GB_MAC_ENABLE_TX_RX 0x00000005 39#define NETXEN_GB_MAC_PAUSED_FRMS 0x00000020 40 41static long phy_lock_timeout = 100000000; 42 43static inline int phy_lock(struct netxen_adapter *adapter) 44{ 45 int i; 46 int done = 0, timeout = 0; 47 48 while (!done) { 49 done = 50 readl(pci_base_offset 51 (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK))); 52 if (done == 1) 53 break; 54 if (timeout >= phy_lock_timeout) { 55 return -1; 56 } 57 timeout++; 58 if (!in_atomic()) 59 schedule(); 60 else { 61 for (i = 0; i < 20; i++) 62 cpu_relax(); 63 } 64 } 65 66 writel(PHY_LOCK_DRIVER, 67 NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID)); 68 return 0; 69} 70 71static inline int phy_unlock(struct netxen_adapter *adapter) 72{ 73 readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK))); 74 75 return 0; 76} 77 78/* 79 * netxen_niu_gbe_phy_read - read a register from the GbE PHY via 80 * mii management interface. 81 * 82 * Note: The MII management interface goes through port 0. 83 * Individual phys are addressed as follows: 84 * @param phy [15:8] phy id 85 * @param reg [7:0] register number 86 * 87 * @returns 0 on success 88 * -1 on error 89 * 90 */ 91int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, 92 __u32 * readval) 93{ 94 long timeout = 0; 95 long result = 0; 96 long restore = 0; 97 long phy = physical_port[adapter->portnum]; 98 __u32 address; 99 __u32 command; 100 __u32 status; 101 __u32 mac_cfg0; 102 103 if (phy_lock(adapter) != 0) { 104 return -1; 105 } 106 107 /* 108 * MII mgmt all goes through port 0 MAC interface, 109 * so it cannot be in reset 110 */ 111 112 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), 113 &mac_cfg0, 4)) 114 return -EIO; 115 if (netxen_gb_get_soft_reset(mac_cfg0)) { 116 __u32 temp; 117 temp = 0; 118 netxen_gb_tx_reset_pb(temp); 119 netxen_gb_rx_reset_pb(temp); 120 netxen_gb_tx_reset_mac(temp); 121 netxen_gb_rx_reset_mac(temp); 122 if (netxen_nic_hw_write_wx(adapter, 123 NETXEN_NIU_GB_MAC_CONFIG_0(0), 124 &temp, 4)) 125 return -EIO; 126 restore = 1; 127 } 128 129 address = 0; 130 netxen_gb_mii_mgmt_reg_addr(address, reg); 131 netxen_gb_mii_mgmt_phy_addr(address, phy); 132 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), 133 &address, 4)) 134 return -EIO; 135 command = 0; /* turn off any prior activity */ 136 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), 137 &command, 4)) 138 return -EIO; 139 /* send read command */ 140 netxen_gb_mii_mgmt_set_read_cycle(command); 141 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), 142 &command, 4)) 143 return -EIO; 144 145 status = 0; 146 do { 147 if (netxen_nic_hw_read_wx(adapter, 148 NETXEN_NIU_GB_MII_MGMT_INDICATE(0), 149 &status, 4)) 150 return -EIO; 151 timeout++; 152 } while ((netxen_get_gb_mii_mgmt_busy(status) 153 || netxen_get_gb_mii_mgmt_notvalid(status)) 154 && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); 155 156 if (timeout < NETXEN_NIU_PHY_WAITMAX) { 157 if (netxen_nic_hw_read_wx(adapter, 158 NETXEN_NIU_GB_MII_MGMT_STATUS(0), 159 readval, 4)) 160 return -EIO; 161 result = 0; 162 } else 163 result = -1; 164 165 if (restore) 166 if (netxen_nic_hw_write_wx(adapter, 167 NETXEN_NIU_GB_MAC_CONFIG_0(0), 168 &mac_cfg0, 4)) 169 return -EIO; 170 phy_unlock(adapter); 171 return result; 172} 173 174/* 175 * netxen_niu_gbe_phy_write - write a register to the GbE PHY via 176 * mii management interface. 177 * 178 * Note: The MII management interface goes through port 0. 179 * Individual phys are addressed as follows: 180 * @param phy [15:8] phy id 181 * @param reg [7:0] register number 182 * 183 * @returns 0 on success 184 * -1 on error 185 * 186 */ 187int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, 188 __u32 val) 189{ 190 long timeout = 0; 191 long result = 0; 192 long restore = 0; 193 long phy = physical_port[adapter->portnum]; 194 __u32 address; 195 __u32 command; 196 __u32 status; 197 __u32 mac_cfg0; 198 199 /* 200 * MII mgmt all goes through port 0 MAC interface, so it 201 * cannot be in reset 202 */ 203 204 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), 205 &mac_cfg0, 4)) 206 return -EIO; 207 if (netxen_gb_get_soft_reset(mac_cfg0)) { 208 __u32 temp; 209 temp = 0; 210 netxen_gb_tx_reset_pb(temp); 211 netxen_gb_rx_reset_pb(temp); 212 netxen_gb_tx_reset_mac(temp); 213 netxen_gb_rx_reset_mac(temp); 214 215 if (netxen_nic_hw_write_wx(adapter, 216 NETXEN_NIU_GB_MAC_CONFIG_0(0), 217 &temp, 4)) 218 return -EIO; 219 restore = 1; 220 } 221 222 command = 0; /* turn off any prior activity */ 223 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), 224 &command, 4)) 225 return -EIO; 226 227 address = 0; 228 netxen_gb_mii_mgmt_reg_addr(address, reg); 229 netxen_gb_mii_mgmt_phy_addr(address, phy); 230 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), 231 &address, 4)) 232 return -EIO; 233 234 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), 235 &val, 4)) 236 return -EIO; 237 238 status = 0; 239 do { 240 if (netxen_nic_hw_read_wx(adapter, 241 NETXEN_NIU_GB_MII_MGMT_INDICATE(0), 242 &status, 4)) 243 return -EIO; 244 timeout++; 245 } while ((netxen_get_gb_mii_mgmt_busy(status)) 246 && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); 247 248 if (timeout < NETXEN_NIU_PHY_WAITMAX) 249 result = 0; 250 else 251 result = -EIO; 252 253 /* restore the state of port 0 MAC in case we tampered with it */ 254 if (restore) 255 if (netxen_nic_hw_write_wx(adapter, 256 NETXEN_NIU_GB_MAC_CONFIG_0(0), 257 &mac_cfg0, 4)) 258 return -EIO; 259 260 return result; 261} 262 263int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter) 264{ 265 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f); 266 return 0; 267} 268 269int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter) 270{ 271 int result = 0; 272 __u32 enable = 0; 273 netxen_set_phy_int_link_status_changed(enable); 274 netxen_set_phy_int_autoneg_completed(enable); 275 netxen_set_phy_int_speed_changed(enable); 276 277 if (0 != 278 netxen_niu_gbe_phy_write(adapter, 279 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 280 enable)) 281 result = -EIO; 282 283 return result; 284} 285 286int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter) 287{ 288 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f); 289 return 0; 290} 291 292int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter) 293{ 294 int result = 0; 295 if (0 != 296 netxen_niu_gbe_phy_write(adapter, 297 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0)) 298 result = -EIO; 299 300 return result; 301} 302 303int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter) 304{ 305 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1); 306 return 0; 307} 308 309int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter) 310{ 311 int result = 0; 312 if (0 != 313 netxen_niu_gbe_phy_write(adapter, 314 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, 315 -EIO)) 316 result = -EIO; 317 318 return result; 319} 320 321/* 322 * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC 323 * 324 */ 325void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, 326 int port, long enable) 327{ 328 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); 329 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 330 0x80000000); 331 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 332 0x0000f0025); 333 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 334 0xf1ff); 335 netxen_crb_writelit_adapter(adapter, 336 NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0); 337 netxen_crb_writelit_adapter(adapter, 338 NETXEN_NIU_GB0_MII_MODE + (port << 3), 1); 339 netxen_crb_writelit_adapter(adapter, 340 (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); 341 netxen_crb_writelit_adapter(adapter, 342 NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); 343 344 if (enable) { 345 /* 346 * Do NOT enable flow control until a suitable solution for 347 * shutting down pause frames is found. 348 */ 349 netxen_crb_writelit_adapter(adapter, 350 NETXEN_NIU_GB_MAC_CONFIG_0(port), 351 0x5); 352 } 353 354 if (netxen_niu_gbe_enable_phy_interrupts(adapter)) 355 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); 356 if (netxen_niu_gbe_clear_phy_interrupts(adapter)) 357 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); 358} 359 360/* 361 * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC 362 */ 363void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, 364 int port, long enable) 365{ 366 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); 367 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 368 0x80000000); 369 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 370 0x0000f0025); 371 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 372 0xf2ff); 373 netxen_crb_writelit_adapter(adapter, 374 NETXEN_NIU_GB0_MII_MODE + (port << 3), 0); 375 netxen_crb_writelit_adapter(adapter, 376 NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1); 377 netxen_crb_writelit_adapter(adapter, 378 (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); 379 netxen_crb_writelit_adapter(adapter, 380 NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); 381 382 if (enable) { 383 /* 384 * Do NOT enable flow control until a suitable solution for 385 * shutting down pause frames is found. 386 */ 387 netxen_crb_writelit_adapter(adapter, 388 NETXEN_NIU_GB_MAC_CONFIG_0(port), 389 0x5); 390 } 391 392 if (netxen_niu_gbe_enable_phy_interrupts(adapter)) 393 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); 394 if (netxen_niu_gbe_clear_phy_interrupts(adapter)) 395 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); 396} 397 398int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) 399{ 400 int result = 0; 401 __u32 status; 402 if (adapter->disable_phy_interrupts) 403 adapter->disable_phy_interrupts(adapter); 404 mdelay(2); 405 406 if (0 == 407 netxen_niu_gbe_phy_read(adapter, 408 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 409 &status)) { 410 if (netxen_get_phy_link(status)) { 411 if (netxen_get_phy_speed(status) == 2) { 412 netxen_niu_gbe_set_gmii_mode(adapter, port, 1); 413 } else if ((netxen_get_phy_speed(status) == 1) 414 || (netxen_get_phy_speed(status) == 0)) { 415 netxen_niu_gbe_set_mii_mode(adapter, port, 1); 416 } else { 417 result = -1; 418 } 419 420 } else { 421 /* 422 * We don't have link. Cable must be unconnected. 423 * Enable phy interrupts so we take action when 424 * plugged in. 425 */ 426 427 netxen_crb_writelit_adapter(adapter, 428 NETXEN_NIU_GB_MAC_CONFIG_0 429 (port), 430 NETXEN_GB_MAC_SOFT_RESET); 431 netxen_crb_writelit_adapter(adapter, 432 NETXEN_NIU_GB_MAC_CONFIG_0 433 (port), 434 NETXEN_GB_MAC_RESET_PROT_BLK 435 | NETXEN_GB_MAC_ENABLE_TX_RX 436 | 437 NETXEN_GB_MAC_PAUSED_FRMS); 438 if (netxen_niu_gbe_clear_phy_interrupts(adapter)) 439 printk(KERN_ERR PFX 440 "ERROR clearing PHY interrupts\n"); 441 if (netxen_niu_gbe_enable_phy_interrupts(adapter)) 442 printk(KERN_ERR PFX 443 "ERROR enabling PHY interrupts\n"); 444 if (netxen_niu_gbe_clear_phy_interrupts(adapter)) 445 printk(KERN_ERR PFX 446 "ERROR clearing PHY interrupts\n"); 447 result = -1; 448 } 449 } else { 450 result = -EIO; 451 } 452 return result; 453} 454 455int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) 456{ 457 u32 portnum = physical_port[adapter->portnum]; 458 459 netxen_crb_writelit_adapter(adapter, 460 NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); 461 netxen_crb_writelit_adapter(adapter, 462 NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5); 463 464 return 0; 465} 466 467/* 468 * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts 469 * @param enable 0 means don't enable the port 470 * 1 means enable (or re-enable) the port 471 */ 472int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, 473 int port, long enable) 474{ 475 int result = 0; 476 __u32 int_src; 477 478 printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" 479 " (device enable = %d)\n", (int)port, (int)enable); 480 481 /* 482 * The read of the PHY INT status will clear the pending 483 * interrupt status 484 */ 485 if (netxen_niu_gbe_phy_read(adapter, 486 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, 487 &int_src) != 0) 488 result = -EINVAL; 489 else { 490 printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src); 491 if (netxen_get_phy_int_jabber(int_src)) 492 printk(KERN_INFO PFX "jabber Interrupt "); 493 if (netxen_get_phy_int_polarity_changed(int_src)) 494 printk(KERN_INFO PFX "polarity changed "); 495 if (netxen_get_phy_int_energy_detect(int_src)) 496 printk(KERN_INFO PFX "energy detect \n"); 497 if (netxen_get_phy_int_downshift(int_src)) 498 printk(KERN_INFO PFX "downshift \n"); 499 if (netxen_get_phy_int_mdi_xover_changed(int_src)) 500 printk(KERN_INFO PFX "mdi_xover_changed "); 501 if (netxen_get_phy_int_fifo_over_underflow(int_src)) 502 printk(KERN_INFO PFX "fifo_over_underflow "); 503 if (netxen_get_phy_int_false_carrier(int_src)) 504 printk(KERN_INFO PFX "false_carrier "); 505 if (netxen_get_phy_int_symbol_error(int_src)) 506 printk(KERN_INFO PFX "symbol_error "); 507 if (netxen_get_phy_int_autoneg_completed(int_src)) 508 printk(KERN_INFO PFX "autoneg_completed "); 509 if (netxen_get_phy_int_page_received(int_src)) 510 printk(KERN_INFO PFX "page_received "); 511 if (netxen_get_phy_int_duplex_changed(int_src)) 512 printk(KERN_INFO PFX "duplex_changed "); 513 if (netxen_get_phy_int_autoneg_error(int_src)) 514 printk(KERN_INFO PFX "autoneg_error "); 515 if ((netxen_get_phy_int_speed_changed(int_src)) 516 || (netxen_get_phy_int_link_status_changed(int_src))) { 517 __u32 status; 518 519 printk(KERN_INFO PFX 520 "speed_changed or link status changed"); 521 if (netxen_niu_gbe_phy_read 522 (adapter, 523 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 524 &status) == 0) { 525 if (netxen_get_phy_speed(status) == 2) { 526 printk 527 (KERN_INFO PFX "Link speed changed" 528 " to 1000 Mbps\n"); 529 netxen_niu_gbe_set_gmii_mode(adapter, 530 port, 531 enable); 532 } else if (netxen_get_phy_speed(status) == 1) { 533 printk 534 (KERN_INFO PFX "Link speed changed" 535 " to 100 Mbps\n"); 536 netxen_niu_gbe_set_mii_mode(adapter, 537 port, 538 enable); 539 } else if (netxen_get_phy_speed(status) == 0) { 540 printk 541 (KERN_INFO PFX "Link speed changed" 542 " to 10 Mbps\n"); 543 netxen_niu_gbe_set_mii_mode(adapter, 544 port, 545 enable); 546 } else { 547 printk(KERN_ERR PFX "ERROR reading" 548 "PHY status. Illegal speed.\n"); 549 result = -1; 550 } 551 } else { 552 printk(KERN_ERR PFX 553 "ERROR reading PHY status.\n"); 554 result = -1; 555 } 556 557 } 558 printk(KERN_INFO "\n"); 559 } 560 return result; 561} 562 563/* 564 * Return the current station MAC address. 565 * Note that the passed-in value must already be in network byte order. 566 */ 567int netxen_niu_macaddr_get(struct netxen_adapter *adapter, 568 netxen_ethernet_macaddr_t * addr) 569{ 570 u32 stationhigh; 571 u32 stationlow; 572 int phy = physical_port[adapter->portnum]; 573 u8 val[8]; 574 575 if (addr == NULL) 576 return -EINVAL; 577 if ((phy < 0) || (phy > 3)) 578 return -EINVAL; 579 580 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), 581 &stationhigh, 4)) 582 return -EIO; 583 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), 584 &stationlow, 4)) 585 return -EIO; 586 ((__le32 *)val)[1] = cpu_to_le32(stationhigh); 587 ((__le32 *)val)[0] = cpu_to_le32(stationlow); 588 589 memcpy(addr, val + 2, 6); 590 591 return 0; 592} 593 594/* 595 * Set the station MAC address. 596 * Note that the passed-in value must already be in network byte order. 597 */ 598int netxen_niu_macaddr_set(struct netxen_adapter *adapter, 599 netxen_ethernet_macaddr_t addr) 600{ 601 u8 temp[4]; 602 u32 val; 603 int phy = physical_port[adapter->portnum]; 604 unsigned char mac_addr[6]; 605 int i; 606 607 for (i = 0; i < 10; i++) { 608 temp[0] = temp[1] = 0; 609 memcpy(temp + 2, addr, 2); 610 val = le32_to_cpu(*(__le32 *)temp); 611 if (netxen_nic_hw_write_wx 612 (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) 613 return -EIO; 614 615 memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); 616 val = le32_to_cpu(*(__le32 *)temp); 617 if (netxen_nic_hw_write_wx 618 (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) 619 return -2; 620 621 netxen_niu_macaddr_get(adapter, 622 (netxen_ethernet_macaddr_t *) mac_addr); 623 if (memcmp(mac_addr, addr, 6) == 0) 624 break; 625 } 626 627 if (i == 10) { 628 printk(KERN_ERR "%s: cannot set Mac addr for %s\n", 629 netxen_nic_driver_name, adapter->netdev->name); 630 printk(KERN_ERR "MAC address set: " 631 "%02x:%02x:%02x:%02x:%02x:%02x.\n", 632 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 633 634 printk(KERN_ERR "MAC address get: " 635 "%02x:%02x:%02x:%02x:%02x:%02x.\n", 636 mac_addr[0], 637 mac_addr[1], 638 mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 639 } 640 return 0; 641} 642 643/* Enable a GbE interface */ 644int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, 645 int port, netxen_niu_gbe_ifmode_t mode) 646{ 647 __u32 mac_cfg0; 648 __u32 mac_cfg1; 649 __u32 mii_cfg; 650 651 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 652 return -EINVAL; 653 654 mac_cfg0 = 0; 655 netxen_gb_soft_reset(mac_cfg0); 656 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 657 &mac_cfg0, 4)) 658 return -EIO; 659 mac_cfg0 = 0; 660 netxen_gb_enable_tx(mac_cfg0); 661 netxen_gb_enable_rx(mac_cfg0); 662 netxen_gb_unset_rx_flowctl(mac_cfg0); 663 netxen_gb_tx_reset_pb(mac_cfg0); 664 netxen_gb_rx_reset_pb(mac_cfg0); 665 netxen_gb_tx_reset_mac(mac_cfg0); 666 netxen_gb_rx_reset_mac(mac_cfg0); 667 668 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 669 &mac_cfg0, 4)) 670 return -EIO; 671 mac_cfg1 = 0; 672 netxen_gb_set_preamblelen(mac_cfg1, 0xf); 673 netxen_gb_set_duplex(mac_cfg1); 674 netxen_gb_set_crc_enable(mac_cfg1); 675 netxen_gb_set_padshort(mac_cfg1); 676 netxen_gb_set_checklength(mac_cfg1); 677 netxen_gb_set_hugeframes(mac_cfg1); 678 679 if (mode == NETXEN_NIU_10_100_MB) { 680 netxen_gb_set_intfmode(mac_cfg1, 1); 681 if (netxen_nic_hw_write_wx(adapter, 682 NETXEN_NIU_GB_MAC_CONFIG_1(port), 683 &mac_cfg1, 4)) 684 return -EIO; 685 686 /* set mii mode */ 687 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + 688 (port << 3), 0); 689 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + 690 (port << 3), 1); 691 692 } else if (mode == NETXEN_NIU_1000_MB) { 693 netxen_gb_set_intfmode(mac_cfg1, 2); 694 if (netxen_nic_hw_write_wx(adapter, 695 NETXEN_NIU_GB_MAC_CONFIG_1(port), 696 &mac_cfg1, 4)) 697 return -EIO; 698 /* set gmii mode */ 699 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + 700 (port << 3), 0); 701 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + 702 (port << 3), 1); 703 } 704 mii_cfg = 0; 705 netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); 706 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 707 &mii_cfg, 4)) 708 return -EIO; 709 mac_cfg0 = 0; 710 netxen_gb_enable_tx(mac_cfg0); 711 netxen_gb_enable_rx(mac_cfg0); 712 netxen_gb_unset_rx_flowctl(mac_cfg0); 713 netxen_gb_unset_tx_flowctl(mac_cfg0); 714 715 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 716 &mac_cfg0, 4)) 717 return -EIO; 718 return 0; 719} 720 721/* Disable a GbE interface */ 722int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) 723{ 724 __u32 mac_cfg0; 725 u32 port = physical_port[adapter->portnum]; 726 727 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 728 return -EINVAL; 729 mac_cfg0 = 0; 730 netxen_gb_soft_reset(mac_cfg0); 731 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 732 &mac_cfg0, 4)) 733 return -EIO; 734 return 0; 735} 736 737/* Disable an XG interface */ 738int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) 739{ 740 __u32 mac_cfg; 741 u32 port = physical_port[adapter->portnum]; 742 743 if (port != 0) 744 return -EINVAL; 745 mac_cfg = 0; 746 netxen_xg_soft_reset(mac_cfg); 747 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0, 748 &mac_cfg, 4)) 749 return -EIO; 750 return 0; 751} 752 753/* Set promiscuous mode for a GbE interface */ 754int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, 755 netxen_niu_prom_mode_t mode) 756{ 757 __u32 reg; 758 u32 port = physical_port[adapter->portnum]; 759 760 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 761 return -EINVAL; 762 763 /* save previous contents */ 764 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, 765 ®, 4)) 766 return -EIO; 767 if (mode == NETXEN_NIU_PROMISC_MODE) { 768 switch (port) { 769 case 0: 770 netxen_clear_gb_drop_gb0(reg); 771 break; 772 case 1: 773 netxen_clear_gb_drop_gb1(reg); 774 break; 775 case 2: 776 netxen_clear_gb_drop_gb2(reg); 777 break; 778 case 3: 779 netxen_clear_gb_drop_gb3(reg); 780 break; 781 default: 782 return -EIO; 783 } 784 } else { 785 switch (port) { 786 case 0: 787 netxen_set_gb_drop_gb0(reg); 788 break; 789 case 1: 790 netxen_set_gb_drop_gb1(reg); 791 break; 792 case 2: 793 netxen_set_gb_drop_gb2(reg); 794 break; 795 case 3: 796 netxen_set_gb_drop_gb3(reg); 797 break; 798 default: 799 return -EIO; 800 } 801 } 802 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, 803 ®, 4)) 804 return -EIO; 805 return 0; 806} 807 808/* 809 * Set the MAC address for an XG port 810 * Note that the passed-in value must already be in network byte order. 811 */ 812int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, 813 netxen_ethernet_macaddr_t addr) 814{ 815 int phy = physical_port[adapter->portnum]; 816 u8 temp[4]; 817 u32 val; 818 819 if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) 820 return -EIO; 821 822 temp[0] = temp[1] = 0; 823 switch (phy) { 824 case 0: 825 memcpy(temp + 2, addr, 2); 826 val = le32_to_cpu(*(__le32 *)temp); 827 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, 828 &val, 4)) 829 return -EIO; 830 831 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); 832 val = le32_to_cpu(*(__le32 *)temp); 833 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, 834 &val, 4)) 835 return -EIO; 836 break; 837 838 case 1: 839 memcpy(temp + 2, addr, 2); 840 val = le32_to_cpu(*(__le32 *)temp); 841 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, 842 &val, 4)) 843 return -EIO; 844 845 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); 846 val = le32_to_cpu(*(__le32 *)temp); 847 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, 848 &val, 4)) 849 return -EIO; 850 break; 851 852 default: 853 printk(KERN_ERR "Unknown port %d\n", phy); 854 break; 855 } 856 857 return 0; 858} 859 860/* 861 * Return the current station MAC address. 862 * Note that the passed-in value must already be in network byte order. 863 */ 864int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, 865 netxen_ethernet_macaddr_t * addr) 866{ 867 int phy = physical_port[adapter->portnum]; 868 u32 stationhigh; 869 u32 stationlow; 870 u8 val[8]; 871 872 if (addr == NULL) 873 return -EINVAL; 874 if (phy != 0) 875 return -EINVAL; 876 877 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, 878 &stationhigh, 4)) 879 return -EIO; 880 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, 881 &stationlow, 4)) 882 return -EIO; 883 ((__le32 *)val)[1] = cpu_to_le32(stationhigh); 884 ((__le32 *)val)[0] = cpu_to_le32(stationlow); 885 886 memcpy(addr, val + 2, 6); 887 888 return 0; 889} 890 891int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 892 netxen_niu_prom_mode_t mode) 893{ 894 __u32 reg; 895 u32 port = physical_port[adapter->portnum]; 896 897 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) 898 return -EINVAL; 899 900 if (netxen_nic_hw_read_wx(adapter, 901 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) 902 return -EIO; 903 if (mode == NETXEN_NIU_PROMISC_MODE) 904 reg = (reg | 0x2000UL); 905 else 906 reg = (reg & ~0x2000UL); 907 908 netxen_crb_writelit_adapter(adapter, 909 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); 910 911 return 0; 912} 913