diff options
author | Mithlesh Thukral <mithlesh@netxen.com> | 2007-04-20 10:55:26 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 11:01:06 -0400 |
commit | 6c80b18df3537d1221ab34555c150bccbfd90260 (patch) | |
tree | b82c057feb8a4c5c4ba0171b268599ea357eb2a9 /drivers/net/netxen/netxen_nic_ethtool.c | |
parent | 5d512f5594f9f4829b099c87f7bc6f683ef146ca (diff) |
NetXen: Port swap feature for multi port cards
NetXen: Port Swap feature
This patch will allow a port numbers on the card to be swapped in
host driver. This feature is applicable to cards having more than
1 port.
Signed-off by: Milan Bag <mbag@netxen.com>
Signed-off by: Mithlesh Thukral <mithlesh@netxen.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_ethtool.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 143 |
1 files changed, 97 insertions, 46 deletions
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 24c68f42584d..16fabb377488 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -40,8 +40,8 @@ | |||
40 | #include <linux/ethtool.h> | 40 | #include <linux/ethtool.h> |
41 | #include <linux/version.h> | 41 | #include <linux/version.h> |
42 | 42 | ||
43 | #include "netxen_nic_hw.h" | ||
44 | #include "netxen_nic.h" | 43 | #include "netxen_nic.h" |
44 | #include "netxen_nic_hw.h" | ||
45 | #include "netxen_nic_phan_reg.h" | 45 | #include "netxen_nic_phan_reg.h" |
46 | 46 | ||
47 | struct netxen_nic_stats { | 47 | struct netxen_nic_stats { |
@@ -379,7 +379,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | |||
379 | for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { | 379 | for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { |
380 | /* GB: port specific registers */ | 380 | /* GB: port specific registers */ |
381 | if (mode == 0 && i >= 19) | 381 | if (mode == 0 && i >= 19) |
382 | window = adapter->portnum * | 382 | window = physical_port[adapter->portnum] * |
383 | NETXEN_NIC_PORT_WINDOW; | 383 | NETXEN_NIC_PORT_WINDOW; |
384 | 384 | ||
385 | NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. | 385 | NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. |
@@ -537,16 +537,43 @@ netxen_nic_get_pauseparam(struct net_device *dev, | |||
537 | { | 537 | { |
538 | struct netxen_adapter *adapter = netdev_priv(dev); | 538 | struct netxen_adapter *adapter = netdev_priv(dev); |
539 | __u32 val; | 539 | __u32 val; |
540 | int port = physical_port[adapter->portnum]; | ||
540 | 541 | ||
541 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { | 542 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { |
543 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) | ||
544 | return; | ||
542 | /* get flow control settings */ | 545 | /* get flow control settings */ |
543 | netxen_nic_read_w0(adapter, | 546 | netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port), |
544 | NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum), | 547 | &val); |
545 | &val); | ||
546 | pause->rx_pause = netxen_gb_get_rx_flowctl(val); | 548 | pause->rx_pause = netxen_gb_get_rx_flowctl(val); |
547 | pause->tx_pause = netxen_gb_get_tx_flowctl(val); | 549 | netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val); |
548 | /* get autoneg settings */ | 550 | switch (port) { |
549 | pause->autoneg = adapter->link_autoneg; | 551 | case 0: |
552 | pause->tx_pause = !(netxen_gb_get_gb0_mask(val)); | ||
553 | break; | ||
554 | case 1: | ||
555 | pause->tx_pause = !(netxen_gb_get_gb1_mask(val)); | ||
556 | break; | ||
557 | case 2: | ||
558 | pause->tx_pause = !(netxen_gb_get_gb2_mask(val)); | ||
559 | break; | ||
560 | case 3: | ||
561 | default: | ||
562 | pause->tx_pause = !(netxen_gb_get_gb3_mask(val)); | ||
563 | break; | ||
564 | } | ||
565 | } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { | ||
566 | if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) | ||
567 | return; | ||
568 | pause->rx_pause = 1; | ||
569 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val); | ||
570 | if (port == 0) | ||
571 | pause->tx_pause = !(netxen_xg_get_xg0_mask(val)); | ||
572 | else | ||
573 | pause->tx_pause = !(netxen_xg_get_xg1_mask(val)); | ||
574 | } else { | ||
575 | printk(KERN_ERR"%s: Unknown board type: %x\n", | ||
576 | netxen_nic_driver_name, adapter->ahw.board_type); | ||
550 | } | 577 | } |
551 | } | 578 | } |
552 | 579 | ||
@@ -556,39 +583,74 @@ netxen_nic_set_pauseparam(struct net_device *dev, | |||
556 | { | 583 | { |
557 | struct netxen_adapter *adapter = netdev_priv(dev); | 584 | struct netxen_adapter *adapter = netdev_priv(dev); |
558 | __u32 val; | 585 | __u32 val; |
559 | unsigned int autoneg; | 586 | int port = physical_port[adapter->portnum]; |
560 | |||
561 | /* read mode */ | 587 | /* read mode */ |
562 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { | 588 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) { |
589 | if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) | ||
590 | return -EIO; | ||
563 | /* set flow control */ | 591 | /* set flow control */ |
564 | netxen_nic_read_w0(adapter, | 592 | netxen_nic_read_w0(adapter, |
565 | NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum), | 593 | NETXEN_NIU_GB_MAC_CONFIG_0(port), &val); |
566 | (u32 *) & val); | 594 | |
567 | if (pause->tx_pause) | ||
568 | netxen_gb_tx_flowctl(val); | ||
569 | else | ||
570 | netxen_gb_unset_tx_flowctl(val); | ||
571 | if (pause->rx_pause) | 595 | if (pause->rx_pause) |
572 | netxen_gb_rx_flowctl(val); | 596 | netxen_gb_rx_flowctl(val); |
573 | else | 597 | else |
574 | netxen_gb_unset_rx_flowctl(val); | 598 | netxen_gb_unset_rx_flowctl(val); |
575 | 599 | ||
576 | netxen_nic_write_w0(adapter, | 600 | netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), |
577 | NETXEN_NIU_GB_MAC_CONFIG_0(adapter->portnum), | 601 | val); |
578 | *&val); | ||
579 | /* set autoneg */ | 602 | /* set autoneg */ |
580 | autoneg = pause->autoneg; | 603 | netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val); |
581 | if (adapter->phy_write | 604 | switch (port) { |
582 | && adapter->phy_write(adapter, | 605 | case 0: |
583 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, | 606 | if (pause->tx_pause) |
584 | autoneg) != 0) | 607 | netxen_gb_unset_gb0_mask(val); |
608 | else | ||
609 | netxen_gb_set_gb0_mask(val); | ||
610 | break; | ||
611 | case 1: | ||
612 | if (pause->tx_pause) | ||
613 | netxen_gb_unset_gb1_mask(val); | ||
614 | else | ||
615 | netxen_gb_set_gb1_mask(val); | ||
616 | break; | ||
617 | case 2: | ||
618 | if (pause->tx_pause) | ||
619 | netxen_gb_unset_gb2_mask(val); | ||
620 | else | ||
621 | netxen_gb_set_gb2_mask(val); | ||
622 | break; | ||
623 | case 3: | ||
624 | default: | ||
625 | if (pause->tx_pause) | ||
626 | netxen_gb_unset_gb3_mask(val); | ||
627 | else | ||
628 | netxen_gb_set_gb3_mask(val); | ||
629 | break; | ||
630 | } | ||
631 | netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); | ||
632 | } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { | ||
633 | if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) | ||
585 | return -EIO; | 634 | return -EIO; |
586 | else { | 635 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val); |
587 | adapter->link_autoneg = pause->autoneg; | 636 | if (port == 0) { |
588 | return 0; | 637 | if (pause->tx_pause) |
638 | netxen_xg_unset_xg0_mask(val); | ||
639 | else | ||
640 | netxen_xg_set_xg0_mask(val); | ||
641 | } else { | ||
642 | if (pause->tx_pause) | ||
643 | netxen_xg_unset_xg1_mask(val); | ||
644 | else | ||
645 | netxen_xg_set_xg1_mask(val); | ||
589 | } | 646 | } |
590 | } else | 647 | netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); |
591 | return -EOPNOTSUPP; | 648 | } else { |
649 | printk(KERN_ERR "%s: Unknown board type: %x\n", | ||
650 | netxen_nic_driver_name, | ||
651 | adapter->ahw.board_type); | ||
652 | } | ||
653 | return 0; | ||
592 | } | 654 | } |
593 | 655 | ||
594 | static int netxen_nic_reg_test(struct net_device *dev) | 656 | static int netxen_nic_reg_test(struct net_device *dev) |
@@ -619,23 +681,12 @@ static void | |||
619 | netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, | 681 | netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, |
620 | u64 * data) | 682 | u64 * data) |
621 | { | 683 | { |
622 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* offline tests */ | 684 | memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN); |
623 | /* link test */ | 685 | if ((data[0] = netxen_nic_reg_test(dev))) |
624 | if ((data[1] = (u64) netxen_nic_test_link(dev))) | 686 | eth_test->flags |= ETH_TEST_FL_FAILED; |
625 | eth_test->flags |= ETH_TEST_FL_FAILED; | 687 | /* link test */ |
626 | 688 | if ((data[1] = (u64) netxen_nic_test_link(dev))) | |
627 | /* register tests */ | 689 | eth_test->flags |= ETH_TEST_FL_FAILED; |
628 | if ((data[0] = netxen_nic_reg_test(dev))) | ||
629 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
630 | } else { /* online tests */ | ||
631 | /* register tests */ | ||
632 | if((data[0] = netxen_nic_reg_test(dev))) | ||
633 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
634 | |||
635 | /* link test */ | ||
636 | if ((data[1] = (u64) netxen_nic_test_link(dev))) | ||
637 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
638 | } | ||
639 | } | 690 | } |
640 | 691 | ||
641 | static void | 692 | static void |