aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2009-06-09 01:39:32 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-10 04:04:14 -0400
commite4552f51ceefcf51b79c5bf8dafc7abb4bb7657d (patch)
treee151217b00245847863e64f09286bc1d2735d7de /drivers
parent542512e4824c1cecc05478f279dccbde1d8bf97a (diff)
qlge: Add support for varied pcie function numbers.
Currently we support only PCIe NIC functions zero and one, and FCoE functions as 3 and 4. Future configurations can mix these up in any fashion. This patch removes the 0-1 dependancy and allows usage of any of the 4 functions. We also find the alternate NIC function (if exist) and determine our port number based on the comparison of the two functions: Lower function number gets first port, higher function gets second port. Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/qlge/qlge.h14
-rw-r--r--drivers/net/qlge/qlge_main.c60
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 */
72enum {
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);
1581void ql_mpi_port_cfg_work(struct work_struct *work); 1594void ql_mpi_port_cfg_work(struct work_struct *work);
1582int ql_mb_get_fw_state(struct ql_adapter *qdev); 1595int ql_mb_get_fw_state(struct ql_adapter *qdev);
1583int ql_cam_route_initialize(struct ql_adapter *qdev); 1596int ql_cam_route_initialize(struct ql_adapter *qdev);
1597int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
1584int ql_mb_about_fw(struct ql_adapter *qdev); 1598int 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 */
3688static 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
3681static void ql_get_board_info(struct ql_adapter *qdev) 3714static 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
3706static void ql_release_all(struct pci_dev *pdev) 3749static 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);