Skip to content

Commit

Permalink
qlge: Add support for varied pcie function numbers.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ron Mercer authored and David S. Miller committed Jun 10, 2009
1 parent 542512e commit e4552f5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 6 deletions.
14 changes: 14 additions & 0 deletions drivers/net/qlge/qlge.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@

#define DB_PAGE_SIZE 4096

/* MPI test register definitions. This register
* is used for determining alternate NIC function's
* PCI->func number.
*/
enum {
MPI_TEST_FUNC_PORT_CFG = 0x1002,
MPI_TEST_NIC1_FUNC_SHIFT = 1,
MPI_TEST_NIC2_FUNC_SHIFT = 5,
MPI_TEST_NIC_FUNC_MASK = 0x00000007,
};

/*
* Processor Address Register (PROC_ADDR) bit definitions.
*/
Expand Down Expand Up @@ -1432,6 +1443,8 @@ struct ql_adapter {
u32 chip_rev_id;
u32 fw_rev_id;
u32 func; /* PCI function for this adapter */
u32 alt_func; /* PCI function for alternate adapter */
u32 port; /* Port number this adapter */

spinlock_t adapter_lock;
spinlock_t hw_lock;
Expand Down Expand Up @@ -1581,6 +1594,7 @@ void ql_mpi_idc_work(struct work_struct *work);
void ql_mpi_port_cfg_work(struct work_struct *work);
int ql_mb_get_fw_state(struct ql_adapter *qdev);
int ql_cam_route_initialize(struct ql_adapter *qdev);
int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
int ql_mb_about_fw(struct ql_adapter *qdev);

#if 1
Expand Down
60 changes: 54 additions & 6 deletions drivers/net/qlge/qlge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
/* Get flash offset for function and adjust
* for dword access.
*/
if (!qdev->func)
if (!qdev->port)
offset = FUNC0_FLASH_OFFSET / sizeof(u32);
else
offset = FUNC1_FLASH_OFFSET / sizeof(u32);
Expand Down Expand Up @@ -744,7 +744,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev)
/* Second function's parameters follow the first
* function's.
*/
if (qdev->func)
if (qdev->port)
offset = size;

if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
Expand Down Expand Up @@ -3220,9 +3220,10 @@ static void ql_display_dev_info(struct net_device *ndev)
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);

QPRINTK(qdev, PROBE, INFO,
"Function #%d, NIC Roll %d, NIC Rev = %d, "
"Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
"XG Roll = %d, XG Rev = %d.\n",
qdev->func,
qdev->port,
qdev->chip_rev_id & 0x0000000f,
qdev->chip_rev_id >> 4 & 0x0000000f,
qdev->chip_rev_id >> 8 & 0x0000000f,
Expand Down Expand Up @@ -3677,12 +3678,53 @@ static struct nic_operations qla8000_nic_ops = {
.port_initialize = ql_8000_port_initialize,
};

/* Find the pcie function number for the other NIC
* on this chip. Since both NIC functions share a
* common firmware we have the lowest enabled function
* do any common work. Examples would be resetting
* after a fatal firmware error, or doing a firmware
* coredump.
*/
static int ql_get_alt_pcie_func(struct ql_adapter *qdev)
{
int status = 0;
u32 temp;
u32 nic_func1, nic_func2;

status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG,
&temp);
if (status)
return status;

nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) &
MPI_TEST_NIC_FUNC_MASK);
nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) &
MPI_TEST_NIC_FUNC_MASK);

if (qdev->func == nic_func1)
qdev->alt_func = nic_func2;
else if (qdev->func == nic_func2)
qdev->alt_func = nic_func1;
else
status = -EIO;

return status;
}

static void ql_get_board_info(struct ql_adapter *qdev)
static int ql_get_board_info(struct ql_adapter *qdev)
{
int status;
qdev->func =
(ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT;
if (qdev->func) {
if (qdev->func > 3)
return -EIO;

status = ql_get_alt_pcie_func(qdev);
if (status)
return status;

qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1;
if (qdev->port) {
qdev->xg_sem_mask = SEM_XGMAC1_MASK;
qdev->port_link_up = STS_PL1;
qdev->port_init = STS_PI1;
Expand All @@ -3701,6 +3743,7 @@ static void ql_get_board_info(struct ql_adapter *qdev)
qdev->nic_ops = &qla8012_nic_ops;
else if (qdev->device_id == QLGE_DEVICE_ID_8000)
qdev->nic_ops = &qla8000_nic_ops;
return status;
}

static void ql_release_all(struct pci_dev *pdev)
Expand Down Expand Up @@ -3795,7 +3838,12 @@ static int __devinit ql_init_device(struct pci_dev *pdev,

qdev->ndev = ndev;
qdev->pdev = pdev;
ql_get_board_info(qdev);
err = ql_get_board_info(qdev);
if (err) {
dev_err(&pdev->dev, "Register access failed.\n");
err = -EIO;
goto err_out;
}
qdev->msg_enable = netif_msg_init(debug, default_msg);
spin_lock_init(&qdev->hw_lock);
spin_lock_init(&qdev->stats_lock);
Expand Down

0 comments on commit e4552f5

Please sign in to comment.