aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2009-02-26 05:08:35 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-27 01:28:09 -0500
commitb0c2aadfa4d2194615ba8f5630be7ae686b9ed01 (patch)
tree4843831c1cf39df7aefb7fb5733753b9921805f2 /drivers/net
parent125844eaff0e9600c92a753995564fd93c807f3c (diff)
qlge: Prepare to add new device.
This organizes a few calls into a function table to enable adding new devices. Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/qlge/qlge.h17
-rw-r--r--drivers/net/qlge/qlge_main.c80
2 files changed, 78 insertions, 19 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 2103fe6ff3a5..7bf18c6d7bc0 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -28,7 +28,7 @@
28 } while (0) 28 } while (0)
29 29
30#define QLGE_VENDOR_ID 0x1077 30#define QLGE_VENDOR_ID 0x1077
31#define QLGE_DEVICE_ID 0x8012 31#define QLGE_DEVICE_ID_8012 0x8012
32 32
33#define MAX_CPUS 8 33#define MAX_CPUS 8
34#define MAX_TX_RINGS MAX_CPUS 34#define MAX_TX_RINGS MAX_CPUS
@@ -798,7 +798,7 @@ struct mbox_params {
798 int out_count; 798 int out_count;
799}; 799};
800 800
801struct flash_params { 801struct flash_params_8012 {
802 u8 dev_id_str[4]; 802 u8 dev_id_str[4];
803 __le16 size; 803 __le16 size;
804 __le16 csum; 804 __le16 csum;
@@ -808,6 +808,9 @@ struct flash_params {
808 __le16 res; 808 __le16 res;
809}; 809};
810 810
811union flash_params {
812 struct flash_params_8012 flash_params_8012;
813};
811 814
812/* 815/*
813 * doorbell space for the rx ring context 816 * doorbell space for the rx ring context
@@ -1367,6 +1370,12 @@ enum {
1367 CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580, 1370 CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580,
1368}; 1371};
1369 1372
1373struct nic_operations {
1374
1375 int (*get_flash) (struct ql_adapter *);
1376 int (*port_initialize) (struct ql_adapter *);
1377};
1378
1370/* 1379/*
1371 * The main Adapter structure definition. 1380 * The main Adapter structure definition.
1372 * This structure has all fields relevant to the hardware. 1381 * This structure has all fields relevant to the hardware.
@@ -1444,7 +1453,7 @@ struct ql_adapter {
1444 u32 port_init; 1453 u32 port_init;
1445 u32 link_status; 1454 u32 link_status;
1446 1455
1447 struct flash_params flash; 1456 union flash_params flash;
1448 1457
1449 struct net_device_stats stats; 1458 struct net_device_stats stats;
1450 struct workqueue_struct *q_workqueue; 1459 struct workqueue_struct *q_workqueue;
@@ -1452,6 +1461,8 @@ struct ql_adapter {
1452 struct delayed_work asic_reset_work; 1461 struct delayed_work asic_reset_work;
1453 struct delayed_work mpi_reset_work; 1462 struct delayed_work mpi_reset_work;
1454 struct delayed_work mpi_work; 1463 struct delayed_work mpi_work;
1464 struct nic_operations *nic_ops;
1465 u16 device_id;
1455}; 1466};
1456 1467
1457/* 1468/*
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index b144b6becfea..d1d8f05d5a11 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -75,7 +75,7 @@ module_param(irq_type, int, MSIX_IRQ);
75MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy."); 75MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
76 76
77static struct pci_device_id qlge_pci_tbl[] __devinitdata = { 77static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
78 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID)}, 78 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
79 /* required last entry */ 79 /* required last entry */
80 {0,} 80 {0,}
81}; 81};
@@ -623,6 +623,28 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
623 623
624} 624}
625 625
626static int ql_validate_flash(struct ql_adapter *qdev, u32 size, const char *str)
627{
628 int status, i;
629 u16 csum = 0;
630 __le16 *flash = (__le16 *)&qdev->flash;
631
632 status = strncmp((char *)&qdev->flash, str, 4);
633 if (status) {
634 QPRINTK(qdev, IFUP, ERR, "Invalid flash signature.\n");
635 return status;
636 }
637
638 for (i = 0; i < size; i++)
639 csum += le16_to_cpu(*flash++);
640
641 if (csum)
642 QPRINTK(qdev, IFUP, ERR,
643 "Invalid flash checksum, csum = 0x%.04x.\n", csum);
644
645 return csum;
646}
647
626static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data) 648static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
627{ 649{
628 int status = 0; 650 int status = 0;
@@ -647,23 +669,24 @@ exit:
647 return status; 669 return status;
648} 670}
649 671
650static int ql_get_flash_params(struct ql_adapter *qdev) 672static int ql_get_8012_flash_params(struct ql_adapter *qdev)
651{ 673{
652 int i; 674 int i;
653 int status; 675 int status;
654 __le32 *p = (__le32 *)&qdev->flash; 676 __le32 *p = (__le32 *)&qdev->flash;
655 u32 offset = 0; 677 u32 offset = 0;
678 u32 size = sizeof(struct flash_params_8012) / sizeof(u32);
656 679
657 /* Second function's parameters follow the first 680 /* Second function's parameters follow the first
658 * function's. 681 * function's.
659 */ 682 */
660 if (qdev->func) 683 if (qdev->func)
661 offset = sizeof(qdev->flash) / sizeof(u32); 684 offset = size;
662 685
663 if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) 686 if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
664 return -ETIMEDOUT; 687 return -ETIMEDOUT;
665 688
666 for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) { 689 for (i = 0; i < size; i++, p++) {
667 status = ql_read_flash_word(qdev, i+offset, p); 690 status = ql_read_flash_word(qdev, i+offset, p);
668 if (status) { 691 if (status) {
669 QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n"); 692 QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
@@ -671,6 +694,25 @@ static int ql_get_flash_params(struct ql_adapter *qdev)
671 } 694 }
672 695
673 } 696 }
697
698 status = ql_validate_flash(qdev,
699 sizeof(struct flash_params_8012) / sizeof(u16),
700 "8012");
701 if (status) {
702 QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
703 status = -EINVAL;
704 goto exit;
705 }
706
707 if (!is_valid_ether_addr(qdev->flash.flash_params_8012.mac_addr)) {
708 status = -EINVAL;
709 goto exit;
710 }
711
712 memcpy(qdev->ndev->dev_addr,
713 qdev->flash.flash_params_8012.mac_addr,
714 qdev->ndev->addr_len);
715
674exit: 716exit:
675 ql_sem_unlock(qdev, SEM_FLASH_MASK); 717 ql_sem_unlock(qdev, SEM_FLASH_MASK);
676 return status; 718 return status;
@@ -747,7 +789,7 @@ exit:
747 * This functionality may be done in the MPI firmware at a 789 * This functionality may be done in the MPI firmware at a
748 * later date. 790 * later date.
749 */ 791 */
750static int ql_port_initialize(struct ql_adapter *qdev) 792static int ql_8012_port_initialize(struct ql_adapter *qdev)
751{ 793{
752 int status = 0; 794 int status = 0;
753 u32 data; 795 u32 data;
@@ -2994,11 +3036,12 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
2994 } 3036 }
2995 } 3037 }
2996 3038
2997 status = ql_port_initialize(qdev); 3039 /* Initialize the port and set the max framesize. */
2998 if (status) { 3040 status = qdev->nic_ops->port_initialize(qdev);
2999 QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n"); 3041 if (status) {
3000 return status; 3042 QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
3001 } 3043 return status;
3044 }
3002 3045
3003 /* Set up the MAC address and frame routing filter. */ 3046 /* Set up the MAC address and frame routing filter. */
3004 status = ql_cam_route_initialize(qdev); 3047 status = ql_cam_route_initialize(qdev);
@@ -3509,6 +3552,12 @@ static void ql_asic_reset_work(struct work_struct *work)
3509 ql_cycle_adapter(qdev); 3552 ql_cycle_adapter(qdev);
3510} 3553}
3511 3554
3555static struct nic_operations qla8012_nic_ops = {
3556 .get_flash = ql_get_8012_flash_params,
3557 .port_initialize = ql_8012_port_initialize,
3558};
3559
3560
3512static void ql_get_board_info(struct ql_adapter *qdev) 3561static void ql_get_board_info(struct ql_adapter *qdev)
3513{ 3562{
3514 qdev->func = 3563 qdev->func =
@@ -3527,6 +3576,9 @@ static void ql_get_board_info(struct ql_adapter *qdev)
3527 qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO; 3576 qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO;
3528 } 3577 }
3529 qdev->chip_rev_id = ql_read32(qdev, REV_ID); 3578 qdev->chip_rev_id = ql_read32(qdev, REV_ID);
3579 qdev->device_id = qdev->pdev->device;
3580 if (qdev->device_id == QLGE_DEVICE_ID_8012)
3581 qdev->nic_ops = &qla8012_nic_ops;
3530} 3582}
3531 3583
3532static void ql_release_all(struct pci_dev *pdev) 3584static void ql_release_all(struct pci_dev *pdev)
@@ -3619,24 +3671,20 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3619 goto err_out; 3671 goto err_out;
3620 } 3672 }
3621 3673
3622 ql_get_board_info(qdev);
3623 qdev->ndev = ndev; 3674 qdev->ndev = ndev;
3624 qdev->pdev = pdev; 3675 qdev->pdev = pdev;
3676 ql_get_board_info(qdev);
3625 qdev->msg_enable = netif_msg_init(debug, default_msg); 3677 qdev->msg_enable = netif_msg_init(debug, default_msg);
3626 spin_lock_init(&qdev->hw_lock); 3678 spin_lock_init(&qdev->hw_lock);
3627 spin_lock_init(&qdev->stats_lock); 3679 spin_lock_init(&qdev->stats_lock);
3628 3680
3629 /* make sure the EEPROM is good */ 3681 /* make sure the EEPROM is good */
3630 err = ql_get_flash_params(qdev); 3682 err = qdev->nic_ops->get_flash(qdev);
3631 if (err) { 3683 if (err) {
3632 dev_err(&pdev->dev, "Invalid FLASH.\n"); 3684 dev_err(&pdev->dev, "Invalid FLASH.\n");
3633 goto err_out; 3685 goto err_out;
3634 } 3686 }
3635 3687
3636 if (!is_valid_ether_addr(qdev->flash.mac_addr))
3637 goto err_out;
3638
3639 memcpy(ndev->dev_addr, qdev->flash.mac_addr, ndev->addr_len);
3640 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); 3688 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
3641 3689
3642 /* Set up the default ring sizes. */ 3690 /* Set up the default ring sizes. */