Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.24 908 lines 24 kB view raw
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 DECLARE_MAC_BUF(mac); 607 608 for (i = 0; i < 10; i++) { 609 temp[0] = temp[1] = 0; 610 memcpy(temp + 2, addr, 2); 611 val = le32_to_cpu(*(__le32 *)temp); 612 if (netxen_nic_hw_write_wx 613 (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) 614 return -EIO; 615 616 memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); 617 val = le32_to_cpu(*(__le32 *)temp); 618 if (netxen_nic_hw_write_wx 619 (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) 620 return -2; 621 622 netxen_niu_macaddr_get(adapter, 623 (netxen_ethernet_macaddr_t *) mac_addr); 624 if (memcmp(mac_addr, addr, 6) == 0) 625 break; 626 } 627 628 if (i == 10) { 629 printk(KERN_ERR "%s: cannot set Mac addr for %s\n", 630 netxen_nic_driver_name, adapter->netdev->name); 631 printk(KERN_ERR "MAC address set: %s.\n", 632 print_mac(mac, addr)); 633 printk(KERN_ERR "MAC address get: %s.\n", 634 print_mac(mac, mac_addr)); 635 } 636 return 0; 637} 638 639/* Enable a GbE interface */ 640int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, 641 int port, netxen_niu_gbe_ifmode_t mode) 642{ 643 __u32 mac_cfg0; 644 __u32 mac_cfg1; 645 __u32 mii_cfg; 646 647 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 648 return -EINVAL; 649 650 mac_cfg0 = 0; 651 netxen_gb_soft_reset(mac_cfg0); 652 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 653 &mac_cfg0, 4)) 654 return -EIO; 655 mac_cfg0 = 0; 656 netxen_gb_enable_tx(mac_cfg0); 657 netxen_gb_enable_rx(mac_cfg0); 658 netxen_gb_unset_rx_flowctl(mac_cfg0); 659 netxen_gb_tx_reset_pb(mac_cfg0); 660 netxen_gb_rx_reset_pb(mac_cfg0); 661 netxen_gb_tx_reset_mac(mac_cfg0); 662 netxen_gb_rx_reset_mac(mac_cfg0); 663 664 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 665 &mac_cfg0, 4)) 666 return -EIO; 667 mac_cfg1 = 0; 668 netxen_gb_set_preamblelen(mac_cfg1, 0xf); 669 netxen_gb_set_duplex(mac_cfg1); 670 netxen_gb_set_crc_enable(mac_cfg1); 671 netxen_gb_set_padshort(mac_cfg1); 672 netxen_gb_set_checklength(mac_cfg1); 673 netxen_gb_set_hugeframes(mac_cfg1); 674 675 if (mode == NETXEN_NIU_10_100_MB) { 676 netxen_gb_set_intfmode(mac_cfg1, 1); 677 if (netxen_nic_hw_write_wx(adapter, 678 NETXEN_NIU_GB_MAC_CONFIG_1(port), 679 &mac_cfg1, 4)) 680 return -EIO; 681 682 /* set mii mode */ 683 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + 684 (port << 3), 0); 685 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + 686 (port << 3), 1); 687 688 } else if (mode == NETXEN_NIU_1000_MB) { 689 netxen_gb_set_intfmode(mac_cfg1, 2); 690 if (netxen_nic_hw_write_wx(adapter, 691 NETXEN_NIU_GB_MAC_CONFIG_1(port), 692 &mac_cfg1, 4)) 693 return -EIO; 694 /* set gmii mode */ 695 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + 696 (port << 3), 0); 697 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + 698 (port << 3), 1); 699 } 700 mii_cfg = 0; 701 netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); 702 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 703 &mii_cfg, 4)) 704 return -EIO; 705 mac_cfg0 = 0; 706 netxen_gb_enable_tx(mac_cfg0); 707 netxen_gb_enable_rx(mac_cfg0); 708 netxen_gb_unset_rx_flowctl(mac_cfg0); 709 netxen_gb_unset_tx_flowctl(mac_cfg0); 710 711 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 712 &mac_cfg0, 4)) 713 return -EIO; 714 return 0; 715} 716 717/* Disable a GbE interface */ 718int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) 719{ 720 __u32 mac_cfg0; 721 u32 port = physical_port[adapter->portnum]; 722 723 if (port > NETXEN_NIU_MAX_GBE_PORTS) 724 return -EINVAL; 725 mac_cfg0 = 0; 726 netxen_gb_soft_reset(mac_cfg0); 727 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 728 &mac_cfg0, 4)) 729 return -EIO; 730 return 0; 731} 732 733/* Disable an XG interface */ 734int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) 735{ 736 __u32 mac_cfg; 737 u32 port = physical_port[adapter->portnum]; 738 739 if (port > NETXEN_NIU_MAX_XG_PORTS) 740 return -EINVAL; 741 742 mac_cfg = 0; 743 if (netxen_nic_hw_write_wx(adapter, 744 NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) 745 return -EIO; 746 return 0; 747} 748 749/* Set promiscuous mode for a GbE interface */ 750int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, 751 netxen_niu_prom_mode_t mode) 752{ 753 __u32 reg; 754 u32 port = physical_port[adapter->portnum]; 755 756 if (port > NETXEN_NIU_MAX_GBE_PORTS) 757 return -EINVAL; 758 759 /* save previous contents */ 760 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, 761 &reg, 4)) 762 return -EIO; 763 if (mode == NETXEN_NIU_PROMISC_MODE) { 764 switch (port) { 765 case 0: 766 netxen_clear_gb_drop_gb0(reg); 767 break; 768 case 1: 769 netxen_clear_gb_drop_gb1(reg); 770 break; 771 case 2: 772 netxen_clear_gb_drop_gb2(reg); 773 break; 774 case 3: 775 netxen_clear_gb_drop_gb3(reg); 776 break; 777 default: 778 return -EIO; 779 } 780 } else { 781 switch (port) { 782 case 0: 783 netxen_set_gb_drop_gb0(reg); 784 break; 785 case 1: 786 netxen_set_gb_drop_gb1(reg); 787 break; 788 case 2: 789 netxen_set_gb_drop_gb2(reg); 790 break; 791 case 3: 792 netxen_set_gb_drop_gb3(reg); 793 break; 794 default: 795 return -EIO; 796 } 797 } 798 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, 799 &reg, 4)) 800 return -EIO; 801 return 0; 802} 803 804/* 805 * Set the MAC address for an XG port 806 * Note that the passed-in value must already be in network byte order. 807 */ 808int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, 809 netxen_ethernet_macaddr_t addr) 810{ 811 int phy = physical_port[adapter->portnum]; 812 u8 temp[4]; 813 u32 val; 814 815 if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) 816 return -EIO; 817 818 temp[0] = temp[1] = 0; 819 switch (phy) { 820 case 0: 821 memcpy(temp + 2, addr, 2); 822 val = le32_to_cpu(*(__le32 *)temp); 823 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, 824 &val, 4)) 825 return -EIO; 826 827 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); 828 val = le32_to_cpu(*(__le32 *)temp); 829 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, 830 &val, 4)) 831 return -EIO; 832 break; 833 834 case 1: 835 memcpy(temp + 2, addr, 2); 836 val = le32_to_cpu(*(__le32 *)temp); 837 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, 838 &val, 4)) 839 return -EIO; 840 841 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); 842 val = le32_to_cpu(*(__le32 *)temp); 843 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, 844 &val, 4)) 845 return -EIO; 846 break; 847 848 default: 849 printk(KERN_ERR "Unknown port %d\n", phy); 850 break; 851 } 852 853 return 0; 854} 855 856/* 857 * Return the current station MAC address. 858 * Note that the passed-in value must already be in network byte order. 859 */ 860int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, 861 netxen_ethernet_macaddr_t * addr) 862{ 863 int phy = physical_port[adapter->portnum]; 864 u32 stationhigh; 865 u32 stationlow; 866 u8 val[8]; 867 868 if (addr == NULL) 869 return -EINVAL; 870 if (phy != 0) 871 return -EINVAL; 872 873 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, 874 &stationhigh, 4)) 875 return -EIO; 876 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, 877 &stationlow, 4)) 878 return -EIO; 879 ((__le32 *)val)[1] = cpu_to_le32(stationhigh); 880 ((__le32 *)val)[0] = cpu_to_le32(stationlow); 881 882 memcpy(addr, val + 2, 6); 883 884 return 0; 885} 886 887int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 888 netxen_niu_prom_mode_t mode) 889{ 890 __u32 reg; 891 u32 port = physical_port[adapter->portnum]; 892 893 if (port > NETXEN_NIU_MAX_XG_PORTS) 894 return -EINVAL; 895 896 if (netxen_nic_hw_read_wx(adapter, 897 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4)) 898 return -EIO; 899 if (mode == NETXEN_NIU_PROMISC_MODE) 900 reg = (reg | 0x2000UL); 901 else 902 reg = (reg & ~0x2000UL); 903 904 netxen_crb_writelit_adapter(adapter, 905 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); 906 907 return 0; 908}