diff options
-rw-r--r-- | drivers/net/qlge/qlge.h | 14 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 60 |
2 files changed, 68 insertions, 6 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 258ef449ea88..5eb52ca08980 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -65,6 +65,17 @@ | |||
65 | 65 | ||
66 | #define DB_PAGE_SIZE 4096 | 66 | #define DB_PAGE_SIZE 4096 |
67 | 67 | ||
68 | /* MPI test register definitions. This register | ||
69 | * is used for determining alternate NIC function's | ||
70 | * PCI->func number. | ||
71 | */ | ||
72 | enum { | ||
73 | MPI_TEST_FUNC_PORT_CFG = 0x1002, | ||
74 | MPI_TEST_NIC1_FUNC_SHIFT = 1, | ||
75 | MPI_TEST_NIC2_FUNC_SHIFT = 5, | ||
76 | MPI_TEST_NIC_FUNC_MASK = 0x00000007, | ||
77 | }; | ||
78 | |||
68 | /* | 79 | /* |
69 | * Processor Address Register (PROC_ADDR) bit definitions. | 80 | * Processor Address Register (PROC_ADDR) bit definitions. |
70 | */ | 81 | */ |
@@ -1432,6 +1443,8 @@ struct ql_adapter { | |||
1432 | u32 chip_rev_id; | 1443 | u32 chip_rev_id; |
1433 | u32 fw_rev_id; | 1444 | u32 fw_rev_id; |
1434 | u32 func; /* PCI function for this adapter */ | 1445 | u32 func; /* PCI function for this adapter */ |
1446 | u32 alt_func; /* PCI function for alternate adapter */ | ||
1447 | u32 port; /* Port number this adapter */ | ||
1435 | 1448 | ||
1436 | spinlock_t adapter_lock; | 1449 | spinlock_t adapter_lock; |
1437 | spinlock_t hw_lock; | 1450 | spinlock_t hw_lock; |
@@ -1581,6 +1594,7 @@ void ql_mpi_idc_work(struct work_struct *work); | |||
1581 | void ql_mpi_port_cfg_work(struct work_struct *work); | 1594 | void ql_mpi_port_cfg_work(struct work_struct *work); |
1582 | int ql_mb_get_fw_state(struct ql_adapter *qdev); | 1595 | int ql_mb_get_fw_state(struct ql_adapter *qdev); |
1583 | int ql_cam_route_initialize(struct ql_adapter *qdev); | 1596 | int ql_cam_route_initialize(struct ql_adapter *qdev); |
1597 | int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); | ||
1584 | int ql_mb_about_fw(struct ql_adapter *qdev); | 1598 | int ql_mb_about_fw(struct ql_adapter *qdev); |
1585 | 1599 | ||
1586 | #if 1 | 1600 | #if 1 |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index d6517eb5bc1d..5055f5b37a73 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -680,7 +680,7 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) | |||
680 | /* Get flash offset for function and adjust | 680 | /* Get flash offset for function and adjust |
681 | * for dword access. | 681 | * for dword access. |
682 | */ | 682 | */ |
683 | if (!qdev->func) | 683 | if (!qdev->port) |
684 | offset = FUNC0_FLASH_OFFSET / sizeof(u32); | 684 | offset = FUNC0_FLASH_OFFSET / sizeof(u32); |
685 | else | 685 | else |
686 | offset = FUNC1_FLASH_OFFSET / sizeof(u32); | 686 | offset = FUNC1_FLASH_OFFSET / sizeof(u32); |
@@ -744,7 +744,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev) | |||
744 | /* Second function's parameters follow the first | 744 | /* Second function's parameters follow the first |
745 | * function's. | 745 | * function's. |
746 | */ | 746 | */ |
747 | if (qdev->func) | 747 | if (qdev->port) |
748 | offset = size; | 748 | offset = size; |
749 | 749 | ||
750 | if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) | 750 | if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) |
@@ -3220,9 +3220,10 @@ static void ql_display_dev_info(struct net_device *ndev) | |||
3220 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); | 3220 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); |
3221 | 3221 | ||
3222 | QPRINTK(qdev, PROBE, INFO, | 3222 | QPRINTK(qdev, PROBE, INFO, |
3223 | "Function #%d, NIC Roll %d, NIC Rev = %d, " | 3223 | "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " |
3224 | "XG Roll = %d, XG Rev = %d.\n", | 3224 | "XG Roll = %d, XG Rev = %d.\n", |
3225 | qdev->func, | 3225 | qdev->func, |
3226 | qdev->port, | ||
3226 | qdev->chip_rev_id & 0x0000000f, | 3227 | qdev->chip_rev_id & 0x0000000f, |
3227 | qdev->chip_rev_id >> 4 & 0x0000000f, | 3228 | qdev->chip_rev_id >> 4 & 0x0000000f, |
3228 | qdev->chip_rev_id >> 8 & 0x0000000f, | 3229 | qdev->chip_rev_id >> 8 & 0x0000000f, |
@@ -3677,12 +3678,53 @@ static struct nic_operations qla8000_nic_ops = { | |||
3677 | .port_initialize = ql_8000_port_initialize, | 3678 | .port_initialize = ql_8000_port_initialize, |
3678 | }; | 3679 | }; |
3679 | 3680 | ||
3681 | /* Find the pcie function number for the other NIC | ||
3682 | * on this chip. Since both NIC functions share a | ||
3683 | * common firmware we have the lowest enabled function | ||
3684 | * do any common work. Examples would be resetting | ||
3685 | * after a fatal firmware error, or doing a firmware | ||
3686 | * coredump. | ||
3687 | */ | ||
3688 | static int ql_get_alt_pcie_func(struct ql_adapter *qdev) | ||
3689 | { | ||
3690 | int status = 0; | ||
3691 | u32 temp; | ||
3692 | u32 nic_func1, nic_func2; | ||
3693 | |||
3694 | status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG, | ||
3695 | &temp); | ||
3696 | if (status) | ||
3697 | return status; | ||
3698 | |||
3699 | nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) & | ||
3700 | MPI_TEST_NIC_FUNC_MASK); | ||
3701 | nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) & | ||
3702 | MPI_TEST_NIC_FUNC_MASK); | ||
3703 | |||
3704 | if (qdev->func == nic_func1) | ||
3705 | qdev->alt_func = nic_func2; | ||
3706 | else if (qdev->func == nic_func2) | ||
3707 | qdev->alt_func = nic_func1; | ||
3708 | else | ||
3709 | status = -EIO; | ||
3710 | |||
3711 | return status; | ||
3712 | } | ||
3680 | 3713 | ||
3681 | static void ql_get_board_info(struct ql_adapter *qdev) | 3714 | static int ql_get_board_info(struct ql_adapter *qdev) |
3682 | { | 3715 | { |
3716 | int status; | ||
3683 | qdev->func = | 3717 | qdev->func = |
3684 | (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; | 3718 | (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; |
3685 | if (qdev->func) { | 3719 | if (qdev->func > 3) |
3720 | return -EIO; | ||
3721 | |||
3722 | status = ql_get_alt_pcie_func(qdev); | ||
3723 | if (status) | ||
3724 | return status; | ||
3725 | |||
3726 | qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1; | ||
3727 | if (qdev->port) { | ||
3686 | qdev->xg_sem_mask = SEM_XGMAC1_MASK; | 3728 | qdev->xg_sem_mask = SEM_XGMAC1_MASK; |
3687 | qdev->port_link_up = STS_PL1; | 3729 | qdev->port_link_up = STS_PL1; |
3688 | qdev->port_init = STS_PI1; | 3730 | qdev->port_init = STS_PI1; |
@@ -3701,6 +3743,7 @@ static void ql_get_board_info(struct ql_adapter *qdev) | |||
3701 | qdev->nic_ops = &qla8012_nic_ops; | 3743 | qdev->nic_ops = &qla8012_nic_ops; |
3702 | else if (qdev->device_id == QLGE_DEVICE_ID_8000) | 3744 | else if (qdev->device_id == QLGE_DEVICE_ID_8000) |
3703 | qdev->nic_ops = &qla8000_nic_ops; | 3745 | qdev->nic_ops = &qla8000_nic_ops; |
3746 | return status; | ||
3704 | } | 3747 | } |
3705 | 3748 | ||
3706 | static void ql_release_all(struct pci_dev *pdev) | 3749 | static void ql_release_all(struct pci_dev *pdev) |
@@ -3795,7 +3838,12 @@ static int __devinit ql_init_device(struct pci_dev *pdev, | |||
3795 | 3838 | ||
3796 | qdev->ndev = ndev; | 3839 | qdev->ndev = ndev; |
3797 | qdev->pdev = pdev; | 3840 | qdev->pdev = pdev; |
3798 | ql_get_board_info(qdev); | 3841 | err = ql_get_board_info(qdev); |
3842 | if (err) { | ||
3843 | dev_err(&pdev->dev, "Register access failed.\n"); | ||
3844 | err = -EIO; | ||
3845 | goto err_out; | ||
3846 | } | ||
3799 | qdev->msg_enable = netif_msg_init(debug, default_msg); | 3847 | qdev->msg_enable = netif_msg_init(debug, default_msg); |
3800 | spin_lock_init(&qdev->hw_lock); | 3848 | spin_lock_init(&qdev->hw_lock); |
3801 | spin_lock_init(&qdev->stats_lock); | 3849 | spin_lock_init(&qdev->stats_lock); |