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

Commit a9083016 authored by Giridhar Malavali's avatar Giridhar Malavali Committed by James Bottomley
Browse files

[SCSI] qla2xxx: Add ISP82XX support.



Enhanced the driver to support new FCoE host bus adapter.

Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent c446c1f9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
		qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o
		qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
        qla_nx.o

obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
+28 −7
Original line number Diff line number Diff line
@@ -41,6 +41,12 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
	struct qla_hw_data *ha = vha->hw;
	int reading;

	if (IS_QLA82XX(ha)) {
		DEBUG2(qla_printk(KERN_INFO, ha,
			"Firmware dump not supported for ISP82xx\n"));
		return count;
	}

	if (off != 0)
		return (0);

@@ -313,7 +319,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
		else if (start == (ha->flt_region_boot * 4) ||
		    start == (ha->flt_region_fw * 4))
			valid = 1;
		else if (IS_QLA25XX(ha) || IS_QLA81XX(ha))
		else if (IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
			valid = 1;
		if (!valid) {
			qla_printk(KERN_WARNING, ha,
@@ -517,6 +523,7 @@ qla2x00_sysfs_write_reset(struct kobject *kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;
	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
	int type;

	if (off != 0)
@@ -551,6 +558,20 @@ qla2x00_sysfs_write_reset(struct kobject *kobj,
			    "MPI reset failed on (%ld).\n", vha->host_no);
		scsi_unblock_requests(vha->host);
		break;
	case 0x2025e:
		if (!IS_QLA82XX(ha) || vha != base_vha) {
			qla_printk(KERN_INFO, ha,
			    "FCoE ctx reset not supported for host%ld.\n",
			    vha->host_no);
			return count;
		}

		qla_printk(KERN_INFO, ha,
		    "Issuing FCoE CTX reset on host%ld.\n", vha->host_no);
		set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
		qla2xxx_wake_dpc(vha);
		qla2x00_wait_for_fcoe_ctx_reset(vha);
		break;
	}
	return count;
}
@@ -836,7 +857,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
			continue;
		if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
			continue;
		if (iter->is4GBp_only == 3 && !IS_QLA81XX(vha->hw))
		if (iter->is4GBp_only == 3 && !(IS_QLA8XXX_TYPE(vha->hw)))
			continue;

		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
@@ -860,7 +881,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
			continue;
		if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
			continue;
		if (iter->is4GBp_only == 3 && !IS_QLA81XX(ha))
		if (iter->is4GBp_only == 3 && !!(IS_QLA8XXX_TYPE(vha->hw)))
			continue;

		sysfs_remove_bin_file(&host->shost_gendev.kobj,
@@ -1233,7 +1254,7 @@ qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr,
{
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	if (!IS_QLA81XX(vha->hw))
	if (!IS_QLA8XXX_TYPE(vha->hw))
		return snprintf(buf, PAGE_SIZE, "\n");

	return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id);
@@ -1245,7 +1266,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev,
{
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	if (!IS_QLA81XX(vha->hw))
	if (!IS_QLA8XXX_TYPE(vha->hw))
		return snprintf(buf, PAGE_SIZE, "\n");

	return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1922,7 +1943,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
	fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
	fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;

	if (IS_QLA81XX(ha))
	if (IS_QLA8XXX_TYPE(ha))
		speed = FC_PORTSPEED_10GBIT;
	else if (IS_QLA25XX(ha))
		speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
+3 −0
Original line number Diff line number Diff line
@@ -769,6 +769,9 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
	void		*nxt;
	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);

	if (IS_QLA82XX(ha))
		return;

	risc_address = ext_mem_cnt = 0;
	flags = 0;

+52 −2
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <scsi/scsi_bsg_fc.h>

#include "qla_bsg.h"
#include "qla_nx.h"
#define QLA2XXX_DRIVER_NAME  "qla2xxx"

/*
@@ -207,6 +208,7 @@ typedef struct srb {
 * SRB flag definitions
 */
#define SRB_DMA_VALID		BIT_0	/* Command sent to ISP */
#define SRB_FCP_CMND_DMA_VALID	BIT_12  /* FCP command in IOCB */

/*
 * SRB extensions.
@@ -417,6 +419,7 @@ typedef union {
		struct device_reg_2xxx isp;
		struct device_reg_24xx isp24;
		struct device_reg_25xxmq isp25mq;
		struct device_reg_82xx isp82;
} device_reg_t;

#define ISP_REQ_Q_IN(ha, reg) \
@@ -2112,6 +2115,7 @@ struct isp_operations {

	int (*get_flash_version) (struct scsi_qla_host *, void *);
	int (*start_scsi) (srb_t *);
	int (*abort_isp) (struct scsi_qla_host *);
};

/* MSI-X Support *************************************************************/
@@ -2386,7 +2390,8 @@ struct qla_hw_data {
#define DT_ISP2532                      BIT_11
#define DT_ISP8432                      BIT_12
#define DT_ISP8001			BIT_13
#define DT_ISP_LAST			(DT_ISP8001 << 1)
#define DT_ISP8021			BIT_14
#define DT_ISP_LAST			(DT_ISP8021 << 1)

#define DT_IIDMA                        BIT_26
#define DT_FWI2                         BIT_27
@@ -2409,6 +2414,7 @@ struct qla_hw_data {
#define IS_QLA2532(ha)  (DT_MASK(ha) & DT_ISP2532)
#define IS_QLA8432(ha)  (DT_MASK(ha) & DT_ISP8432)
#define IS_QLA8001(ha)	(DT_MASK(ha) & DT_ISP8001)
#define IS_QLA82XX(ha)	(DT_MASK(ha) & DT_ISP8021)

#define IS_QLA23XX(ha)  (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
			IS_QLA6312(ha) || IS_QLA6322(ha))
@@ -2419,8 +2425,10 @@ struct qla_hw_data {
#define IS_QLA24XX_TYPE(ha)     (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
				IS_QLA84XX(ha))
#define IS_QLA81XX(ha)		(IS_QLA8001(ha))
#define IS_QLA8XXX_TYPE(ha)	(IS_QLA81XX(ha) || IS_QLA82XX(ha))
#define IS_QLA2XXX_MIDTYPE(ha)	(IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
				IS_QLA25XX(ha) || IS_QLA81XX(ha))
				IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
				IS_QLA82XX(ha))
#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha))
#define IS_NOPOLLING_TYPE(ha)	((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
				(ha)->flags.msix_enabled)
@@ -2603,6 +2611,7 @@ struct qla_hw_data {
	uint32_t        flt_region_npiv_conf;
	uint32_t	flt_region_gold_fw;
	uint32_t	flt_region_fcp_prio;
	uint32_t	flt_region_bootload;

	/* Needed for BEACON */
	uint16_t        beacon_blink_led;
@@ -2634,6 +2643,38 @@ struct qla_hw_data {

	/* FCP_CMND priority support */
	struct qla_fcp_prio_cfg *fcp_prio_cfg;

	struct dma_pool *dl_dma_pool;
#define DSD_LIST_DMA_POOL_SIZE  512

	struct dma_pool *fcp_cmnd_dma_pool;
	mempool_t       *ctx_mempool;
#define FCP_CMND_DMA_POOL_SIZE 512

	unsigned long	nx_pcibase;		/* Base I/O address */
	uint8_t		*nxdb_rd_ptr;		/* Doorbell read pointer */
	unsigned long	nxdb_wr_ptr;		/* Door bell write pointer */
	unsigned long	first_page_group_start;
	unsigned long	first_page_group_end;

	uint32_t	crb_win;
	uint32_t	curr_window;
	uint32_t	ddr_mn_window;
	unsigned long	mn_win_crb;
	unsigned long	ms_win_crb;
	int		qdr_sn_window;
	uint32_t	nx_dev_init_timeout;
	uint32_t	nx_reset_timeout;
	rwlock_t	hw_lock;
	uint16_t	portnum;		/* port number */
	int		link_width;
	struct fw_blob	*hablob;
	struct qla82xx_legacy_intr_set nx_legacy_intr;

	uint16_t	gbl_dsd_inuse;
	uint16_t	gbl_dsd_avail;
	struct list_head gbl_dsd_list;
#define NUM_DSD_CHAIN 4096
};

/*
@@ -2686,10 +2727,13 @@ typedef struct scsi_qla_host {
#define VP_DPC_NEEDED		14	/* wake up for VP dpc handling */
#define UNLOADING		15
#define NPIV_CONFIG_NEEDED	16
#define ISP_UNRECOVERABLE	17
#define FCOE_CTX_RESET_NEEDED	18	/* Initiate FCoE context reset */

	uint32_t	device_flags;
#define SWITCH_FOUND		BIT_0
#define DFLG_NO_CABLE		BIT_1
#define DFLG_DEV_FAILED		BIT_5

	/* ISP configuration data. */
	uint16_t	loop_id;		/* Host adapter loop id */
@@ -2747,6 +2791,8 @@ typedef struct scsi_qla_host {
#define VP_ERR_ADAP_NORESOURCES	5
	struct qla_hw_data *hw;
	struct req_que *req;
	int		fw_heartbeat_counter;
	int		seconds_since_last_heartbeat;
} scsi_qla_host_t;

/*
@@ -2799,6 +2845,10 @@ typedef struct scsi_qla_host {
#define OPTROM_SIZE_24XX	0x100000
#define OPTROM_SIZE_25XX	0x200000
#define OPTROM_SIZE_81XX	0x400000
#define OPTROM_SIZE_82XX	0x800000

#define OPTROM_BURST_SIZE	0x1000
#define OPTROM_BURST_DWORDS	(OPTROM_BURST_SIZE / 4)

#include "qla_gbl.h"
#include "qla_dbg.h"
+85 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_update_fcports(scsi_qla_host_t *);

extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);

extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);

@@ -79,6 +80,9 @@ extern int ql2xmaxqueues;
extern int ql2xmultique_tag;
extern int ql2xfwloadbin;
extern int ql2xetsenable;
extern int ql2xshiftctondsd;
extern int ql2xdbwr;
extern int ql2xdontresethba;

extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -135,6 +139,7 @@ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);

extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
extern int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *);

extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
@@ -157,6 +162,9 @@ int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
						uint16_t, uint16_t, uint8_t);
extern int qla2x00_start_sp(srb_t *);
extern void qla2x00_ctx_sp_free(srb_t *);
extern uint16_t qla24xx_calc_iocbs(uint16_t);
extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t);


/*
 * Global Function Prototypes in qla_mbx.c source file.
@@ -343,6 +351,7 @@ qla24xx_process_response_queue(struct scsi_qla_host *, struct rsp_que *);
extern int qla2x00_request_irqs(struct qla_hw_data *, struct rsp_que *);
extern void qla2x00_free_irqs(scsi_qla_host_t *);

extern int qla2x00_get_data_rate(scsi_qla_host_t *);
/*
 * Global Function Prototypes in qla_sup.c source file.
 */
@@ -466,6 +475,82 @@ extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);

/* qla82xx related functions */

/* PCI related functions */
extern int qla82xx_pci_config(struct scsi_qla_host *);
extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int);
extern int qla82xx_pci_mem_write_2M(struct qla_hw_data *, u64, void *, int);
extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *);
extern int qla82xx_pci_region_offset(struct pci_dev *, int);
extern int qla82xx_pci_region_len(struct pci_dev *, int);
extern int qla82xx_iospace_config(struct qla_hw_data *);

/* Initialization related functions */
extern void qla82xx_reset_chip(struct scsi_qla_host *);
extern void qla82xx_config_rings(struct scsi_qla_host *);
extern int qla82xx_nvram_config(struct scsi_qla_host *);
extern int qla82xx_pinit_from_rom(scsi_qla_host_t *);
extern int qla82xx_load_firmware(scsi_qla_host_t *);
extern int qla82xx_reset_hw(scsi_qla_host_t *);
extern int qla82xx_load_risc_blob(scsi_qla_host_t *, uint32_t *);
extern void qla82xx_watchdog(scsi_qla_host_t *);

/* Firmware and flash related functions */
extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern uint8_t *qla82xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
    uint32_t, uint32_t);
extern int qla82xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
    uint32_t, uint32_t);

/* Mailbox related functions */
extern int qla82xx_abort_isp(scsi_qla_host_t *);
extern int qla82xx_restart_isp(scsi_qla_host_t *);

/* IOCB related functions */
extern int qla82xx_start_scsi(srb_t *);

/* Interrupt related */
extern irqreturn_t qla82xx_intr_handler(int, void *);
extern irqreturn_t qla82xx_msi_handler(int, void *);
extern irqreturn_t qla82xx_msix_default(int, void *);
extern irqreturn_t qla82xx_msix_rsp_q(int, void *);
extern void qla82xx_enable_intrs(struct qla_hw_data *);
extern void qla82xx_disable_intrs(struct qla_hw_data *);
extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
extern void qla82xx_poll(int, void *);
extern void qla82xx_init_flags(struct qla_hw_data *);

/* ISP 8021 hardware related */
extern int qla82xx_crb_win_lock(struct qla_hw_data *);
extern void qla82xx_crb_win_unlock(struct qla_hw_data *);
extern int qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *, ulong *);
extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32);
extern int qla82xx_rd_32(struct qla_hw_data *, ulong);
extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int);
extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int);
extern int qla82xx_check_for_bad_spd(struct qla_hw_data *);
extern int qla82xx_load_fw(scsi_qla_host_t *);
extern int qla82xx_rom_lock(struct qla_hw_data *);
extern void qla82xx_rom_unlock(struct qla_hw_data *);
extern int qla82xx_rom_fast_read(struct qla_hw_data *, int , int *);
extern int qla82xx_do_rom_fast_read(struct qla_hw_data *, int, int *);
extern unsigned long qla82xx_decode_crb_addr(unsigned long);

/* ISP 8021 IDC */
extern void qla82xx_clear_drv_active(struct qla_hw_data *);
extern int qla82xx_idc_lock(struct qla_hw_data *);
extern void qla82xx_idc_unlock(struct qla_hw_data *);
extern int qla82xx_device_state_handler(scsi_qla_host_t *);

extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
    size_t, char *);
extern int qla82xx_mbx_intr_enable(scsi_qla_host_t *);
extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *);
extern void qla82xx_start_iocbs(srb_t *);
extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *);
extern void qla82xx_wait_for_pending_commands(scsi_qla_host_t *);

/* BSG related functions */
extern int qla24xx_bsg_request(struct fc_bsg_job *);
extern int qla24xx_bsg_timeout(struct fc_bsg_job *);
Loading