diff options
author | Chien Tung <ctung@neteffect.com> | 2008-09-30 17:49:44 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-09-30 17:49:44 -0400 |
commit | fcb7ad31beda842804167f0645ca54660713bcd6 (patch) | |
tree | 9b8311500887491d74cff655593a102f77db38c1 | |
parent | 54c86a8c838301e8a619e454b686288578002300 (diff) |
RDMA/nes: Add support for 4-port 1G HP blade card
Add support for NetEffect 4 port 1G HP blade card. The mapping
between physical port and MAC is different from the standup card.
Signed-off-by: Chien Tung <ctung@neteffect.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/hw/nes/nes.c | 29 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 66 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 1 |
3 files changed, 76 insertions, 20 deletions
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index b0cab64e5e3d..a5396850680c 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -562,7 +562,26 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
562 | nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ | 562 | nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ |
563 | nesdev->base_doorbell_index = 1; | 563 | nesdev->base_doorbell_index = 1; |
564 | nesdev->doorbell_start = nesdev->nesadapter->doorbell_start; | 564 | nesdev->doorbell_start = nesdev->nesadapter->doorbell_start; |
565 | nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) % nesdev->nesadapter->port_count; | 565 | if (nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { |
566 | switch (PCI_FUNC(nesdev->pcidev->devfn) % | ||
567 | nesdev->nesadapter->port_count) { | ||
568 | case 1: | ||
569 | nesdev->mac_index = 2; | ||
570 | break; | ||
571 | case 2: | ||
572 | nesdev->mac_index = 1; | ||
573 | break; | ||
574 | case 3: | ||
575 | nesdev->mac_index = 3; | ||
576 | break; | ||
577 | case 0: | ||
578 | default: | ||
579 | nesdev->mac_index = 0; | ||
580 | } | ||
581 | } else { | ||
582 | nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) % | ||
583 | nesdev->nesadapter->port_count; | ||
584 | } | ||
566 | 585 | ||
567 | tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); | 586 | tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); |
568 | 587 | ||
@@ -581,7 +600,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
581 | nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) | | 600 | nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) | |
582 | (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16)); | 601 | (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16)); |
583 | if (PCI_FUNC(nesdev->pcidev->devfn) < 4) { | 602 | if (PCI_FUNC(nesdev->pcidev->devfn) < 4) { |
584 | nesdev->int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+24)); | 603 | nesdev->int_req |= (1 << (PCI_FUNC(nesdev->mac_index)+24)); |
585 | } | 604 | } |
586 | 605 | ||
587 | /* TODO: This really should be the first driver to load, not function 0 */ | 606 | /* TODO: This really should be the first driver to load, not function 0 */ |
@@ -772,14 +791,14 @@ static ssize_t nes_show_adapter(struct device_driver *ddp, char *buf) | |||
772 | 791 | ||
773 | list_for_each_entry(nesdev, &nes_dev_list, list) { | 792 | list_for_each_entry(nesdev, &nes_dev_list, list) { |
774 | if (i == ee_flsh_adapter) { | 793 | if (i == ee_flsh_adapter) { |
775 | devfn = nesdev->nesadapter->devfn; | 794 | devfn = nesdev->pcidev->devfn; |
776 | bus_number = nesdev->nesadapter->bus_number; | 795 | bus_number = nesdev->pcidev->bus->number; |
777 | break; | 796 | break; |
778 | } | 797 | } |
779 | i++; | 798 | i++; |
780 | } | 799 | } |
781 | 800 | ||
782 | return snprintf(buf, PAGE_SIZE, "%x:%x", bus_number, devfn); | 801 | return snprintf(buf, PAGE_SIZE, "%x:%x\n", bus_number, devfn); |
783 | } | 802 | } |
784 | 803 | ||
785 | static ssize_t nes_store_adapter(struct device_driver *ddp, | 804 | static ssize_t nes_store_adapter(struct device_driver *ddp, |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 1513d4066f1b..bdd98e66f432 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -61,7 +61,7 @@ u32 int_mod_cq_depth_1; | |||
61 | static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq); | 61 | static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq); |
62 | static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count); | 62 | static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count); |
63 | static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | 63 | static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, |
64 | u8 OneG_Mode); | 64 | struct nes_adapter *nesadapter, u8 OneG_Mode); |
65 | static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq); | 65 | static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq); |
66 | static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq); | 66 | static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq); |
67 | static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq); | 67 | static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq); |
@@ -292,9 +292,6 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
292 | 292 | ||
293 | if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0) | 293 | if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0) |
294 | return NULL; | 294 | return NULL; |
295 | if (nes_init_serdes(nesdev, hw_rev, port_count, OneG_Mode)) | ||
296 | return NULL; | ||
297 | nes_init_csr_ne020(nesdev, hw_rev, port_count); | ||
298 | 295 | ||
299 | max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE); | 296 | max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE); |
300 | nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp); | 297 | nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp); |
@@ -353,6 +350,19 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
353 | nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n", | 350 | nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n", |
354 | nesadapter, (u32)sizeof(struct nes_adapter), adapter_size); | 351 | nesadapter, (u32)sizeof(struct nes_adapter), adapter_size); |
355 | 352 | ||
353 | if (nes_read_eeprom_values(nesdev, nesadapter)) { | ||
354 | printk(KERN_ERR PFX "Unable to read EEPROM data.\n"); | ||
355 | kfree(nesadapter); | ||
356 | return NULL; | ||
357 | } | ||
358 | |||
359 | if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter, | ||
360 | OneG_Mode)) { | ||
361 | kfree(nesadapter); | ||
362 | return NULL; | ||
363 | } | ||
364 | nes_init_csr_ne020(nesdev, hw_rev, port_count); | ||
365 | |||
356 | /* populate the new nesadapter */ | 366 | /* populate the new nesadapter */ |
357 | nesadapter->devfn = nesdev->pcidev->devfn; | 367 | nesadapter->devfn = nesdev->pcidev->devfn; |
358 | nesadapter->bus_number = nesdev->pcidev->bus->number; | 368 | nesadapter->bus_number = nesdev->pcidev->bus->number; |
@@ -468,20 +478,25 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
468 | 478 | ||
469 | /* setup port configuration */ | 479 | /* setup port configuration */ |
470 | if (nesadapter->port_count == 1) { | 480 | if (nesadapter->port_count == 1) { |
471 | u32temp = 0x00000000; | 481 | nesadapter->log_port = 0x00000000; |
472 | if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) | 482 | if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) |
473 | nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002); | 483 | nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002); |
474 | else | 484 | else |
475 | nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); | 485 | nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); |
476 | } else { | 486 | } else { |
477 | if (nesadapter->port_count == 2) | 487 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { |
478 | u32temp = 0x00000044; | 488 | nesadapter->log_port = 0x000000D8; |
479 | else | 489 | } else { |
480 | u32temp = 0x000000e4; | 490 | if (nesadapter->port_count == 2) |
491 | nesadapter->log_port = 0x00000044; | ||
492 | else | ||
493 | nesadapter->log_port = 0x000000e4; | ||
494 | } | ||
481 | nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); | 495 | nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); |
482 | } | 496 | } |
483 | 497 | ||
484 | nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT, u32temp); | 498 | nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT, |
499 | nesadapter->log_port); | ||
485 | nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n", | 500 | nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n", |
486 | nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT)); | 501 | nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT)); |
487 | 502 | ||
@@ -706,23 +721,43 @@ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_ | |||
706 | * nes_init_serdes | 721 | * nes_init_serdes |
707 | */ | 722 | */ |
708 | static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | 723 | static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, |
709 | u8 OneG_Mode) | 724 | struct nes_adapter *nesadapter, u8 OneG_Mode) |
710 | { | 725 | { |
711 | int i; | 726 | int i; |
712 | u32 u32temp; | 727 | u32 u32temp; |
728 | u32 serdes_common_control; | ||
713 | 729 | ||
714 | if (hw_rev != NE020_REV) { | 730 | if (hw_rev != NE020_REV) { |
715 | /* init serdes 0 */ | 731 | /* init serdes 0 */ |
716 | 732 | ||
717 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | 733 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); |
718 | if (!OneG_Mode) | 734 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { |
735 | serdes_common_control = nes_read_indexed(nesdev, | ||
736 | NES_IDX_ETH_SERDES_COMMON_CONTROL0); | ||
737 | serdes_common_control |= 0x000000100; | ||
738 | nes_write_indexed(nesdev, | ||
739 | NES_IDX_ETH_SERDES_COMMON_CONTROL0, | ||
740 | serdes_common_control); | ||
741 | } else if (!OneG_Mode) { | ||
719 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); | 742 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); |
720 | if (port_count > 1) { | 743 | } |
744 | if (((port_count > 1) && | ||
745 | (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) || | ||
746 | ((port_count > 2) && | ||
747 | (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) { | ||
721 | /* init serdes 1 */ | 748 | /* init serdes 1 */ |
722 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); | 749 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); |
723 | if (!OneG_Mode) | 750 | if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { |
751 | serdes_common_control = nes_read_indexed(nesdev, | ||
752 | NES_IDX_ETH_SERDES_COMMON_CONTROL1); | ||
753 | serdes_common_control |= 0x000000100; | ||
754 | nes_write_indexed(nesdev, | ||
755 | NES_IDX_ETH_SERDES_COMMON_CONTROL1, | ||
756 | serdes_common_control); | ||
757 | } else if (!OneG_Mode) { | ||
724 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); | 758 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); |
725 | } | 759 | } |
760 | } | ||
726 | } else { | 761 | } else { |
727 | /* init serdes 0 */ | 762 | /* init serdes 0 */ |
728 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); | 763 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); |
@@ -2258,7 +2293,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2258 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); | 2293 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); |
2259 | } | 2294 | } |
2260 | /* read the PHY interrupt status register */ | 2295 | /* read the PHY interrupt status register */ |
2261 | if (nesadapter->OneG_Mode) { | 2296 | if ((nesadapter->OneG_Mode) && |
2297 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
2262 | do { | 2298 | do { |
2263 | nes_read_1G_phy_reg(nesdev, 0x1a, | 2299 | nes_read_1G_phy_reg(nesdev, 0x1a, |
2264 | nesadapter->phy_index[mac_index], &phy_data); | 2300 | nesadapter->phy_index[mac_index], &phy_data); |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 7b81e0ae0076..fc0f063ce248 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -1100,6 +1100,7 @@ struct nes_adapter { | |||
1100 | u8 mac_sw_state[4]; | 1100 | u8 mac_sw_state[4]; |
1101 | u8 mac_link_down[4]; | 1101 | u8 mac_link_down[4]; |
1102 | u8 phy_type[4]; | 1102 | u8 phy_type[4]; |
1103 | u8 log_port; | ||
1103 | 1104 | ||
1104 | /* PCI information */ | 1105 | /* PCI information */ |
1105 | unsigned int devfn; | 1106 | unsigned int devfn; |