Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0c2aadf authored by Ron Mercer's avatar Ron Mercer Committed by David S. Miller
Browse files

qlge: Prepare to add new device.



This organizes a few calls into a function table to enable adding new
devices.

Signed-off-by: default avatarRon Mercer <ron.mercer@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 125844ea
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@
       } while (0)

#define QLGE_VENDOR_ID    0x1077
#define QLGE_DEVICE_ID    0x8012
#define QLGE_DEVICE_ID_8012	0x8012

#define MAX_CPUS 8
#define MAX_TX_RINGS MAX_CPUS
@@ -798,7 +798,7 @@ struct mbox_params {
	int out_count;
};

struct flash_params {
struct flash_params_8012 {
	u8 dev_id_str[4];
	__le16 size;
	__le16 csum;
@@ -808,6 +808,9 @@ struct flash_params {
	__le16 res;
};

union flash_params {
	struct flash_params_8012 flash_params_8012;
};

/*
 * doorbell space for the rx ring context
@@ -1367,6 +1370,12 @@ enum {
	CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580,
};

struct nic_operations {

	int (*get_flash) (struct ql_adapter *);
	int (*port_initialize) (struct ql_adapter *);
};

/*
 * The main Adapter structure definition.
 * This structure has all fields relevant to the hardware.
@@ -1444,7 +1453,7 @@ struct ql_adapter {
	u32 port_init;
	u32 link_status;

	struct flash_params flash;
	union flash_params flash;

	struct net_device_stats stats;
	struct workqueue_struct *q_workqueue;
@@ -1452,6 +1461,8 @@ struct ql_adapter {
	struct delayed_work asic_reset_work;
	struct delayed_work mpi_reset_work;
	struct delayed_work mpi_work;
	struct nic_operations *nic_ops;
	u16 device_id;
};

/*
+64 −16
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ module_param(irq_type, int, MSIX_IRQ);
MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");

static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID)},
	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
	/* required last entry */
	{0,}
};
@@ -623,6 +623,28 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)

}

static int ql_validate_flash(struct ql_adapter *qdev, u32 size, const char *str)
{
	int status, i;
	u16 csum = 0;
	__le16 *flash = (__le16 *)&qdev->flash;

	status = strncmp((char *)&qdev->flash, str, 4);
	if (status) {
		QPRINTK(qdev, IFUP, ERR, "Invalid flash signature.\n");
		return	status;
	}

	for (i = 0; i < size; i++)
		csum += le16_to_cpu(*flash++);

	if (csum)
		QPRINTK(qdev, IFUP, ERR,
			"Invalid flash checksum, csum = 0x%.04x.\n", csum);

	return csum;
}

static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
{
	int status = 0;
@@ -647,23 +669,24 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
	return status;
}

static int ql_get_flash_params(struct ql_adapter *qdev)
static int ql_get_8012_flash_params(struct ql_adapter *qdev)
{
	int i;
	int status;
	__le32 *p = (__le32 *)&qdev->flash;
	u32 offset = 0;
	u32 size = sizeof(struct flash_params_8012) / sizeof(u32);

	/* Second function's parameters follow the first
	 * function's.
	 */
	if (qdev->func)
		offset = sizeof(qdev->flash) / sizeof(u32);
		offset = size;

	if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
		return -ETIMEDOUT;

	for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
	for (i = 0; i < size; i++, p++) {
		status = ql_read_flash_word(qdev, i+offset, p);
		if (status) {
			QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
@@ -671,6 +694,25 @@ static int ql_get_flash_params(struct ql_adapter *qdev)
		}

	}

	status = ql_validate_flash(qdev,
			sizeof(struct flash_params_8012) / sizeof(u16),
			"8012");
	if (status) {
		QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
		status = -EINVAL;
		goto exit;
	}

	if (!is_valid_ether_addr(qdev->flash.flash_params_8012.mac_addr)) {
		status = -EINVAL;
		goto exit;
	}

	memcpy(qdev->ndev->dev_addr,
		qdev->flash.flash_params_8012.mac_addr,
		qdev->ndev->addr_len);

exit:
	ql_sem_unlock(qdev, SEM_FLASH_MASK);
	return status;
@@ -747,7 +789,7 @@ int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data)
 * This functionality may be done in the MPI firmware at a
 * later date.
 */
static int ql_port_initialize(struct ql_adapter *qdev)
static int ql_8012_port_initialize(struct ql_adapter *qdev)
{
	int status = 0;
	u32 data;
@@ -2994,7 +3036,8 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
		}
	}

	status = ql_port_initialize(qdev);
	/* Initialize the port and set the max framesize. */
	status = qdev->nic_ops->port_initialize(qdev);
       if (status) {
              QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
              return status;
@@ -3509,6 +3552,12 @@ static void ql_asic_reset_work(struct work_struct *work)
	ql_cycle_adapter(qdev);
}

static struct nic_operations qla8012_nic_ops = {
	.get_flash		= ql_get_8012_flash_params,
	.port_initialize	= ql_8012_port_initialize,
};


static void ql_get_board_info(struct ql_adapter *qdev)
{
	qdev->func =
@@ -3527,6 +3576,9 @@ static void ql_get_board_info(struct ql_adapter *qdev)
		qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO;
	}
	qdev->chip_rev_id = ql_read32(qdev, REV_ID);
	qdev->device_id = qdev->pdev->device;
	if (qdev->device_id == QLGE_DEVICE_ID_8012)
		qdev->nic_ops = &qla8012_nic_ops;
}

static void ql_release_all(struct pci_dev *pdev)
@@ -3619,24 +3671,20 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
		goto err_out;
	}

	ql_get_board_info(qdev);
	qdev->ndev = ndev;
	qdev->pdev = pdev;
	ql_get_board_info(qdev);
	qdev->msg_enable = netif_msg_init(debug, default_msg);
	spin_lock_init(&qdev->hw_lock);
	spin_lock_init(&qdev->stats_lock);

	/* make sure the EEPROM is good */
	err = ql_get_flash_params(qdev);
	err = qdev->nic_ops->get_flash(qdev);
	if (err) {
		dev_err(&pdev->dev, "Invalid FLASH.\n");
		goto err_out;
	}

	if (!is_valid_ether_addr(qdev->flash.mac_addr))
		goto err_out;

	memcpy(ndev->dev_addr, qdev->flash.mac_addr, ndev->addr_len);
	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);

	/* Set up the default ring sizes. */