diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-05-05 15:05:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-06 18:33:36 -0400 |
commit | 3d0a3cc9d72047e4baa76021c897f64fc84cc543 (patch) | |
tree | 121b07aa7e131380681659734d780042b9c776ca /drivers/net/netxen/netxen_nic_niu.c | |
parent | 5cf4d323f8864dab818d500ec74f2fcb9ad5bf89 (diff) |
netxen: fix bonding support
o Pause traffic during mac addr change.
o Enable setting mac address for NX3031.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_niu.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 154 |
1 files changed, 33 insertions, 121 deletions
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 5e2698bf575a..5941c79be723 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c | |||
@@ -402,76 +402,6 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | |||
402 | return 0; | 402 | return 0; |
403 | } | 403 | } |
404 | 404 | ||
405 | /* | ||
406 | * Return the current station MAC address. | ||
407 | * Note that the passed-in value must already be in network byte order. | ||
408 | */ | ||
409 | static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, | ||
410 | netxen_ethernet_macaddr_t * addr) | ||
411 | { | ||
412 | u32 stationhigh; | ||
413 | u32 stationlow; | ||
414 | int phy = adapter->physical_port; | ||
415 | u8 val[8]; | ||
416 | |||
417 | if (addr == NULL) | ||
418 | return -EINVAL; | ||
419 | if ((phy < 0) || (phy > 3)) | ||
420 | return -EINVAL; | ||
421 | |||
422 | stationhigh = NXRD32(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy)); | ||
423 | stationlow = NXRD32(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy)); | ||
424 | ((__le32 *)val)[1] = cpu_to_le32(stationhigh); | ||
425 | ((__le32 *)val)[0] = cpu_to_le32(stationlow); | ||
426 | |||
427 | memcpy(addr, val + 2, 6); | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * Set the station MAC address. | ||
434 | * Note that the passed-in value must already be in network byte order. | ||
435 | */ | ||
436 | int netxen_niu_macaddr_set(struct netxen_adapter *adapter, | ||
437 | netxen_ethernet_macaddr_t addr) | ||
438 | { | ||
439 | u8 temp[4]; | ||
440 | u32 val; | ||
441 | int phy = adapter->physical_port; | ||
442 | unsigned char mac_addr[6]; | ||
443 | int i; | ||
444 | |||
445 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
446 | return 0; | ||
447 | |||
448 | for (i = 0; i < 10; i++) { | ||
449 | temp[0] = temp[1] = 0; | ||
450 | memcpy(temp + 2, addr, 2); | ||
451 | val = le32_to_cpu(*(__le32 *)temp); | ||
452 | if (NXWR32(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), val)) | ||
453 | return -EIO; | ||
454 | |||
455 | memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); | ||
456 | val = le32_to_cpu(*(__le32 *)temp); | ||
457 | if (NXWR32(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), val)) | ||
458 | return -2; | ||
459 | |||
460 | netxen_niu_macaddr_get(adapter, | ||
461 | (netxen_ethernet_macaddr_t *) mac_addr); | ||
462 | if (memcmp(mac_addr, addr, 6) == 0) | ||
463 | break; | ||
464 | } | ||
465 | |||
466 | if (i == 10) { | ||
467 | printk(KERN_ERR "%s: cannot set Mac addr for %s\n", | ||
468 | netxen_nic_driver_name, adapter->netdev->name); | ||
469 | printk(KERN_ERR "MAC address set: %pM.\n", addr); | ||
470 | printk(KERN_ERR "MAC address get: %pM.\n", mac_addr); | ||
471 | } | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | /* Disable a GbE interface */ | 405 | /* Disable a GbE interface */ |
476 | int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) | 406 | int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) |
477 | { | 407 | { |
@@ -561,57 +491,6 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
561 | return 0; | 491 | return 0; |
562 | } | 492 | } |
563 | 493 | ||
564 | /* | ||
565 | * Set the MAC address for an XG port | ||
566 | * Note that the passed-in value must already be in network byte order. | ||
567 | */ | ||
568 | int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, | ||
569 | netxen_ethernet_macaddr_t addr) | ||
570 | { | ||
571 | int phy = adapter->physical_port; | ||
572 | u8 temp[4]; | ||
573 | u32 val; | ||
574 | |||
575 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
576 | return 0; | ||
577 | |||
578 | if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) | ||
579 | return -EIO; | ||
580 | |||
581 | temp[0] = temp[1] = 0; | ||
582 | switch (phy) { | ||
583 | case 0: | ||
584 | memcpy(temp + 2, addr, 2); | ||
585 | val = le32_to_cpu(*(__le32 *)temp); | ||
586 | if (NXWR32(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, val)) | ||
587 | return -EIO; | ||
588 | |||
589 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); | ||
590 | val = le32_to_cpu(*(__le32 *)temp); | ||
591 | if (NXWR32(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, val)) | ||
592 | return -EIO; | ||
593 | break; | ||
594 | |||
595 | case 1: | ||
596 | memcpy(temp + 2, addr, 2); | ||
597 | val = le32_to_cpu(*(__le32 *)temp); | ||
598 | if (NXWR32(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, val)) | ||
599 | return -EIO; | ||
600 | |||
601 | memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); | ||
602 | val = le32_to_cpu(*(__le32 *)temp); | ||
603 | if (NXWR32(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, val)) | ||
604 | return -EIO; | ||
605 | break; | ||
606 | |||
607 | default: | ||
608 | printk(KERN_ERR "Unknown port %d\n", phy); | ||
609 | break; | ||
610 | } | ||
611 | |||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, | 494 | int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, |
616 | u32 mode) | 495 | u32 mode) |
617 | { | 496 | { |
@@ -636,3 +515,36 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, | |||
636 | 515 | ||
637 | return 0; | 516 | return 0; |
638 | } | 517 | } |
518 | |||
519 | int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) | ||
520 | { | ||
521 | u32 mac_hi, mac_lo; | ||
522 | u32 reg_hi, reg_lo; | ||
523 | |||
524 | u8 phy = adapter->physical_port; | ||
525 | u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ? | ||
526 | NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS; | ||
527 | |||
528 | if (phy >= phy_count) | ||
529 | return -EINVAL; | ||
530 | |||
531 | mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24); | ||
532 | mac_hi = addr[2] | ((u32)addr[3] << 8) | | ||
533 | ((u32)addr[4] << 16) | ((u32)addr[5] << 24); | ||
534 | |||
535 | if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { | ||
536 | reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy); | ||
537 | reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy); | ||
538 | } else { | ||
539 | reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy); | ||
540 | reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy); | ||
541 | } | ||
542 | |||
543 | /* write twice to flush */ | ||
544 | if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi)) | ||
545 | return -EIO; | ||
546 | if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi)) | ||
547 | return -EIO; | ||
548 | |||
549 | return 0; | ||
550 | } | ||