提交 a9083016 编写于 作者: G Giridhar Malavali 提交者: James Bottomley

[SCSI] qla2xxx: Add ISP82XX support.

Enhanced the driver to support new FCoE host bus adapter.
Signed-off-by: NGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
上级 c446c1f9
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ 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 obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
...@@ -41,6 +41,12 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, ...@@ -41,6 +41,12 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
int reading; int reading;
if (IS_QLA82XX(ha)) {
DEBUG2(qla_printk(KERN_INFO, ha,
"Firmware dump not supported for ISP82xx\n"));
return count;
}
if (off != 0) if (off != 0)
return (0); return (0);
...@@ -313,8 +319,8 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, ...@@ -313,8 +319,8 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
else if (start == (ha->flt_region_boot * 4) || else if (start == (ha->flt_region_boot * 4) ||
start == (ha->flt_region_fw * 4)) start == (ha->flt_region_fw * 4))
valid = 1; valid = 1;
else if (IS_QLA25XX(ha) || IS_QLA81XX(ha)) else if (IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
valid = 1; valid = 1;
if (!valid) { if (!valid) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Invalid start region 0x%x/0x%x.\n", start, size); "Invalid start region 0x%x/0x%x.\n", start, size);
...@@ -517,6 +523,7 @@ qla2x00_sysfs_write_reset(struct kobject *kobj, ...@@ -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 scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj))); struct device, kobj)));
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
int type; int type;
if (off != 0) if (off != 0)
...@@ -551,6 +558,20 @@ qla2x00_sysfs_write_reset(struct kobject *kobj, ...@@ -551,6 +558,20 @@ qla2x00_sysfs_write_reset(struct kobject *kobj,
"MPI reset failed on (%ld).\n", vha->host_no); "MPI reset failed on (%ld).\n", vha->host_no);
scsi_unblock_requests(vha->host); scsi_unblock_requests(vha->host);
break; 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; return count;
} }
...@@ -836,7 +857,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) ...@@ -836,7 +857,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
continue; continue;
if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
continue; continue;
if (iter->is4GBp_only == 3 && !IS_QLA81XX(vha->hw)) if (iter->is4GBp_only == 3 && !(IS_QLA8XXX_TYPE(vha->hw)))
continue; continue;
ret = sysfs_create_bin_file(&host->shost_gendev.kobj, ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
...@@ -860,7 +881,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) ...@@ -860,7 +881,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
continue; continue;
if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
continue; continue;
if (iter->is4GBp_only == 3 && !IS_QLA81XX(ha)) if (iter->is4GBp_only == 3 && !!(IS_QLA8XXX_TYPE(vha->hw)))
continue; continue;
sysfs_remove_bin_file(&host->shost_gendev.kobj, sysfs_remove_bin_file(&host->shost_gendev.kobj,
...@@ -1233,7 +1254,7 @@ qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr, ...@@ -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)); 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, "\n");
return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id); return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id);
...@@ -1245,7 +1266,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev, ...@@ -1245,7 +1266,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev,
{ {
scsi_qla_host_t *vha = shost_priv(class_to_shost(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, "\n");
return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\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) ...@@ -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_max_npiv_vports(vha->host) = ha->max_npiv_vports;
fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha))
speed = FC_PORTSPEED_10GBIT; speed = FC_PORTSPEED_10GBIT;
else if (IS_QLA25XX(ha)) else if (IS_QLA25XX(ha))
speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
......
...@@ -769,6 +769,9 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -769,6 +769,9 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
void *nxt; void *nxt;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
if (IS_QLA82XX(ha))
return;
risc_address = ext_mem_cnt = 0; risc_address = ext_mem_cnt = 0;
flags = 0; flags = 0;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <scsi/scsi_bsg_fc.h> #include <scsi/scsi_bsg_fc.h>
#include "qla_bsg.h" #include "qla_bsg.h"
#include "qla_nx.h"
#define QLA2XXX_DRIVER_NAME "qla2xxx" #define QLA2XXX_DRIVER_NAME "qla2xxx"
/* /*
...@@ -207,6 +208,7 @@ typedef struct srb { ...@@ -207,6 +208,7 @@ typedef struct srb {
* SRB flag definitions * SRB flag definitions
*/ */
#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */ #define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
#define SRB_FCP_CMND_DMA_VALID BIT_12 /* FCP command in IOCB */
/* /*
* SRB extensions. * SRB extensions.
...@@ -417,6 +419,7 @@ typedef union { ...@@ -417,6 +419,7 @@ typedef union {
struct device_reg_2xxx isp; struct device_reg_2xxx isp;
struct device_reg_24xx isp24; struct device_reg_24xx isp24;
struct device_reg_25xxmq isp25mq; struct device_reg_25xxmq isp25mq;
struct device_reg_82xx isp82;
} device_reg_t; } device_reg_t;
#define ISP_REQ_Q_IN(ha, reg) \ #define ISP_REQ_Q_IN(ha, reg) \
...@@ -2112,6 +2115,7 @@ struct isp_operations { ...@@ -2112,6 +2115,7 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *); int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *); int (*start_scsi) (srb_t *);
int (*abort_isp) (struct scsi_qla_host *);
}; };
/* MSI-X Support *************************************************************/ /* MSI-X Support *************************************************************/
...@@ -2386,7 +2390,8 @@ struct qla_hw_data { ...@@ -2386,7 +2390,8 @@ struct qla_hw_data {
#define DT_ISP2532 BIT_11 #define DT_ISP2532 BIT_11
#define DT_ISP8432 BIT_12 #define DT_ISP8432 BIT_12
#define DT_ISP8001 BIT_13 #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_IIDMA BIT_26
#define DT_FWI2 BIT_27 #define DT_FWI2 BIT_27
...@@ -2409,6 +2414,7 @@ struct qla_hw_data { ...@@ -2409,6 +2414,7 @@ struct qla_hw_data {
#define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532)
#define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432) #define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432)
#define IS_QLA8001(ha) (DT_MASK(ha) & DT_ISP8001) #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) || \ #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
IS_QLA6312(ha) || IS_QLA6322(ha)) IS_QLA6312(ha) || IS_QLA6322(ha))
...@@ -2419,8 +2425,10 @@ struct qla_hw_data { ...@@ -2419,8 +2425,10 @@ struct qla_hw_data {
#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
IS_QLA84XX(ha)) IS_QLA84XX(ha))
#define IS_QLA81XX(ha) (IS_QLA8001(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) || \ #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_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha))
#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \ #define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
(ha)->flags.msix_enabled) (ha)->flags.msix_enabled)
...@@ -2603,6 +2611,7 @@ struct qla_hw_data { ...@@ -2603,6 +2611,7 @@ struct qla_hw_data {
uint32_t flt_region_npiv_conf; uint32_t flt_region_npiv_conf;
uint32_t flt_region_gold_fw; uint32_t flt_region_gold_fw;
uint32_t flt_region_fcp_prio; uint32_t flt_region_fcp_prio;
uint32_t flt_region_bootload;
/* Needed for BEACON */ /* Needed for BEACON */
uint16_t beacon_blink_led; uint16_t beacon_blink_led;
...@@ -2634,6 +2643,38 @@ struct qla_hw_data { ...@@ -2634,6 +2643,38 @@ struct qla_hw_data {
/* FCP_CMND priority support */ /* FCP_CMND priority support */
struct qla_fcp_prio_cfg *fcp_prio_cfg; 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 { ...@@ -2686,10 +2727,13 @@ typedef struct scsi_qla_host {
#define VP_DPC_NEEDED 14 /* wake up for VP dpc handling */ #define VP_DPC_NEEDED 14 /* wake up for VP dpc handling */
#define UNLOADING 15 #define UNLOADING 15
#define NPIV_CONFIG_NEEDED 16 #define NPIV_CONFIG_NEEDED 16
#define ISP_UNRECOVERABLE 17
#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */
uint32_t device_flags; uint32_t device_flags;
#define SWITCH_FOUND BIT_0 #define SWITCH_FOUND BIT_0
#define DFLG_NO_CABLE BIT_1 #define DFLG_NO_CABLE BIT_1
#define DFLG_DEV_FAILED BIT_5
/* ISP configuration data. */ /* ISP configuration data. */
uint16_t loop_id; /* Host adapter loop id */ uint16_t loop_id; /* Host adapter loop id */
...@@ -2747,6 +2791,8 @@ typedef struct scsi_qla_host { ...@@ -2747,6 +2791,8 @@ typedef struct scsi_qla_host {
#define VP_ERR_ADAP_NORESOURCES 5 #define VP_ERR_ADAP_NORESOURCES 5
struct qla_hw_data *hw; struct qla_hw_data *hw;
struct req_que *req; struct req_que *req;
int fw_heartbeat_counter;
int seconds_since_last_heartbeat;
} scsi_qla_host_t; } scsi_qla_host_t;
/* /*
...@@ -2799,6 +2845,10 @@ typedef struct scsi_qla_host { ...@@ -2799,6 +2845,10 @@ typedef struct scsi_qla_host {
#define OPTROM_SIZE_24XX 0x100000 #define OPTROM_SIZE_24XX 0x100000
#define OPTROM_SIZE_25XX 0x200000 #define OPTROM_SIZE_25XX 0x200000
#define OPTROM_SIZE_81XX 0x400000 #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_gbl.h"
#include "qla_dbg.h" #include "qla_dbg.h"
......
...@@ -44,6 +44,7 @@ extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); ...@@ -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 void qla2x00_update_fcports(scsi_qla_host_t *);
extern int qla2x00_abort_isp(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 *); extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
...@@ -79,6 +80,9 @@ extern int ql2xmaxqueues; ...@@ -79,6 +80,9 @@ extern int ql2xmaxqueues;
extern int ql2xmultique_tag; extern int ql2xmultique_tag;
extern int ql2xfwloadbin; extern int ql2xfwloadbin;
extern int ql2xetsenable; extern int ql2xetsenable;
extern int ql2xshiftctondsd;
extern int ql2xdbwr;
extern int ql2xdontresethba;
extern int qla2x00_loop_reset(scsi_qla_host_t *); extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); 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 *); ...@@ -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_hba_online(scsi_qla_host_t *);
extern int qla2x00_wait_for_chip_reset(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 qla2xxx_wake_dpc(struct scsi_qla_host *);
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *); 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 *, ...@@ -157,6 +162,9 @@ int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
uint16_t, uint16_t, uint8_t); uint16_t, uint16_t, uint8_t);
extern int qla2x00_start_sp(srb_t *); extern int qla2x00_start_sp(srb_t *);
extern void qla2x00_ctx_sp_free(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. * Global Function Prototypes in qla_mbx.c source file.
...@@ -343,6 +351,7 @@ qla24xx_process_response_queue(struct scsi_qla_host *, struct rsp_que *); ...@@ -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 int qla2x00_request_irqs(struct qla_hw_data *, struct rsp_que *);
extern void qla2x00_free_irqs(scsi_qla_host_t *); 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. * 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); ...@@ -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 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); 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 */ /* BSG related functions */
extern int qla24xx_bsg_request(struct fc_bsg_job *); extern int qla24xx_bsg_request(struct fc_bsg_job *);
extern int qla24xx_bsg_timeout(struct fc_bsg_job *); extern int qla24xx_bsg_timeout(struct fc_bsg_job *);
......
...@@ -1535,7 +1535,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha) ...@@ -1535,7 +1535,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter = (struct ct_fdmi_port_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
eiter->len = __constant_cpu_to_be16(4 + 4); eiter->len = __constant_cpu_to_be16(4 + 4);
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha))
eiter->a.sup_speed = __constant_cpu_to_be32( eiter->a.sup_speed = __constant_cpu_to_be32(
FDMI_PORT_SPEED_10GB); FDMI_PORT_SPEED_10GB);
else if (IS_QLA25XX(ha)) else if (IS_QLA25XX(ha))
......
...@@ -328,6 +328,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) ...@@ -328,6 +328,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
if (rval) if (rval)
return (rval); return (rval);
} }
if (IS_QLA84XX(ha)) { if (IS_QLA84XX(ha)) {
ha->cs84xx = qla84xx_get_chip(vha); ha->cs84xx = qla84xx_get_chip(vha);
if (!ha->cs84xx) { if (!ha->cs84xx) {
...@@ -961,6 +962,9 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) ...@@ -961,6 +962,9 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0]; struct req_que *req = ha->req_q_map[0];
if (IS_QLA82XX(ha))
return QLA_SUCCESS;
ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length; ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length;
rval = qla2x00_mbx_reg_test(vha); rval = qla2x00_mbx_reg_test(vha);
...@@ -1183,6 +1187,12 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) ...@@ -1183,6 +1187,12 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
unsigned long flags; unsigned long flags;
uint16_t fw_major_version; uint16_t fw_major_version;
if (IS_QLA82XX(ha)) {
rval = ha->isp_ops->load_risc(vha, &srisc_address);
if (rval == QLA_SUCCESS)
goto enable_82xx_npiv;
}
if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) { if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
/* Disable SRAM, Instruction RAM and GP RAM parity. */ /* Disable SRAM, Instruction RAM and GP RAM parity. */
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
...@@ -1208,6 +1218,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) ...@@ -1208,6 +1218,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
rval = qla2x00_execute_fw(vha, srisc_address); rval = qla2x00_execute_fw(vha, srisc_address);
/* Retrieve firmware information. */ /* Retrieve firmware information. */
if (rval == QLA_SUCCESS) { if (rval == QLA_SUCCESS) {
enable_82xx_npiv:
fw_major_version = ha->fw_major_version; fw_major_version = ha->fw_major_version;
rval = qla2x00_get_fw_version(vha, rval = qla2x00_get_fw_version(vha,
&ha->fw_major_version, &ha->fw_major_version,
...@@ -1232,8 +1243,10 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) ...@@ -1232,8 +1243,10 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
&ha->fw_xcb_count, NULL, NULL, &ha->fw_xcb_count, NULL, NULL,
&ha->max_npiv_vports, NULL); &ha->max_npiv_vports, NULL);
if (!fw_major_version && ql2xallocfwdump) if (!fw_major_version && ql2xallocfwdump) {
qla2x00_alloc_fw_dump(vha); if (!IS_QLA82XX(ha))
qla2x00_alloc_fw_dump(vha);
}
} }
} else { } else {
DEBUG2(printk(KERN_INFO DEBUG2(printk(KERN_INFO
...@@ -1390,6 +1403,9 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha) ...@@ -1390,6 +1403,9 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
int rval; int rval;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
if (IS_QLA82XX(ha))
return;
/* Update Serial Link options. */ /* Update Serial Link options. */
if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0) if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
return; return;
...@@ -1824,7 +1840,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) ...@@ -1824,7 +1840,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
return(rval); return(rval);
} }
static inline void inline void
qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
char *def) char *def)
{ {
...@@ -1832,7 +1848,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, ...@@ -1832,7 +1848,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
uint16_t index; uint16_t index;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
!IS_QLA81XX(ha); !IS_QLA8XXX_TYPE(ha);
if (memcmp(model, BINZERO, len) != 0) { if (memcmp(model, BINZERO, len) != 0) {
strncpy(ha->model_number, model, len); strncpy(ha->model_number, model, len);
...@@ -3552,6 +3568,45 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) ...@@ -3552,6 +3568,45 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
qla2x00_rport_del(fcport); qla2x00_rport_del(fcport);
} }
void
qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
struct scsi_qla_host *tvp;
vha->flags.online = 0;
ha->flags.chip_reset_done = 0;
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
ha->qla_stats.total_isp_aborts++;
qla_printk(KERN_INFO, ha,
"Performing ISP error recovery - ha= %p.\n", ha);
/* Chip reset does not apply to 82XX */
if (!IS_QLA82XX(ha))
ha->isp_ops->reset_chip(vha);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
list_for_each_entry_safe(vp, tvp, &base_vha->hw->vp_list, list)
qla2x00_mark_all_devices_lost(vp, 0);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer,
LOOP_DOWN_TIME);
}
/* Make sure for ISP 82XX IO DMA is complete */
if (IS_QLA82XX(ha))
qla82xx_wait_for_pending_commands(vha);
/* Requeue all commands in outstanding command list. */
qla2x00_abort_all_cmds(vha, DID_RESET << 16);
}
/* /*
* qla2x00_abort_isp * qla2x00_abort_isp
* Resets ISP and aborts all outstanding commands. * Resets ISP and aborts all outstanding commands.
...@@ -3573,27 +3628,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) ...@@ -3573,27 +3628,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
struct req_que *req = ha->req_q_map[0]; struct req_que *req = ha->req_q_map[0];
if (vha->flags.online) { if (vha->flags.online) {
vha->flags.online = 0; qla2x00_abort_isp_cleanup(vha);
ha->flags.chip_reset_done = 0;
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
ha->qla_stats.total_isp_aborts++;
qla_printk(KERN_INFO, ha,
"Performing ISP error recovery - ha= %p.\n", ha);
ha->isp_ops->reset_chip(vha);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer,
LOOP_DOWN_TIME);
}
/* Requeue all commands in outstanding command list. */
qla2x00_abort_all_cmds(vha, DID_RESET << 16);
if (unlikely(pci_channel_offline(ha->pdev) && if (unlikely(pci_channel_offline(ha->pdev) &&
ha->flags.pci_channel_io_perm_failure)) { ha->flags.pci_channel_io_perm_failure)) {
...@@ -3849,6 +3884,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha) ...@@ -3849,6 +3884,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
if (IS_QLA82XX(ha))
return;
vha->flags.online = 0; vha->flags.online = 0;
ha->isp_ops->disable_intrs(ha); ha->isp_ops->disable_intrs(ha);
...@@ -3912,6 +3950,8 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) ...@@ -3912,6 +3950,8 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
} }
ha->nvram_size = sizeof(struct nvram_24xx); ha->nvram_size = sizeof(struct nvram_24xx);
ha->vpd_size = FA_NVRAM_VPD_SIZE; ha->vpd_size = FA_NVRAM_VPD_SIZE;
if (IS_QLA82XX(ha))
ha->vpd_size = FA_VPD_SIZE_82XX;
/* Get VPD data into cache */ /* Get VPD data into cache */
ha->vpd = ha->nvram + VPD_OFFSET; ha->vpd = ha->nvram + VPD_OFFSET;
...@@ -4775,7 +4815,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) ...@@ -4775,7 +4815,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
* Setup driver NVRAM options. * Setup driver NVRAM options.
*/ */
qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name), qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name),
"QLE81XX"); "QLE8XXX");
/* Use alternate WWN? */ /* Use alternate WWN? */
if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { if (nv->host_p & __constant_cpu_to_le32(BIT_15)) {
...@@ -4898,6 +4938,147 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) ...@@ -4898,6 +4938,147 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
return (rval); return (rval);
} }
int
qla82xx_restart_isp(scsi_qla_host_t *vha)
{
int status, rval;
uint32_t wait_time;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
struct rsp_que *rsp = ha->rsp_q_map[0];
struct scsi_qla_host *vp;
struct scsi_qla_host *tvp;
status = qla2x00_init_rings(vha);
if (!status) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
ha->flags.chip_reset_done = 1;
status = qla2x00_fw_ready(vha);
if (!status) {
qla_printk(KERN_INFO, ha,
"%s(): Start configure loop, "
"status = %d\n", __func__, status);
/* Issue a marker after FW becomes ready. */
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
vha->flags.online = 1;
/* Wait at most MAX_TARGET RSCNs for a stable link. */
wait_time = 256;
do {
clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
qla2x00_configure_loop(vha);
wait_time--;
} while (!atomic_read(&vha->loop_down_timer) &&
!(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) &&
wait_time &&
(test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)));
}
/* if no cable then assume it's good */
if ((vha->device_flags & DFLG_NO_CABLE))
status = 0;
qla_printk(KERN_INFO, ha,
"%s(): Configure loop done, status = 0x%x\n",
__func__, status);
}
if (!status) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
if (!atomic_read(&vha->loop_down_timer)) {
/*
* Issue marker command only when we are going
* to start the I/O .
*/
vha->marker_needed = 1;
}
vha->flags.online = 1;
ha->isp_ops->enable_intrs(ha);
ha->isp_abort_cnt = 0;
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
if (ha->fce) {
ha->flags.fce_enabled = 1;
memset(ha->fce, 0,
fce_calc_size(ha->fce_bufs));
rval = qla2x00_enable_fce_trace(vha,
ha->fce_dma, ha->fce_bufs, ha->fce_mb,
&ha->fce_bufs);
if (rval) {
qla_printk(KERN_WARNING, ha,
"Unable to reinitialize FCE "
"(%d).\n", rval);
ha->flags.fce_enabled = 0;
}
}
if (ha->eft) {
memset(ha->eft, 0, EFT_SIZE);
rval = qla2x00_enable_eft_trace(vha,
ha->eft_dma, EFT_NUM_BUFFERS);
if (rval) {
qla_printk(KERN_WARNING, ha,
"Unable to reinitialize EFT "
"(%d).\n", rval);
}
}
} else { /* failed the ISP abort */
vha->flags.online = 1;
if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
if (ha->isp_abort_cnt == 0) {
qla_printk(KERN_WARNING, ha,
"ISP error recovery failed - "
"board disabled\n");
/*
* The next call disables the board
* completely.
*/
ha->isp_ops->reset_adapter(vha);
vha->flags.online = 0;
clear_bit(ISP_ABORT_RETRY,
&vha->dpc_flags);
status = 0;
} else { /* schedule another ISP abort */
ha->isp_abort_cnt--;
qla_printk(KERN_INFO, ha,
"qla%ld: ISP abort - "
"retry remaining %d\n",
vha->host_no, ha->isp_abort_cnt);
status = 1;
}
} else {
ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;
qla_printk(KERN_INFO, ha,
"(%ld): ISP error recovery "
"- retrying (%d) more times\n",
vha->host_no, ha->isp_abort_cnt);
set_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
status = 1;
}
}
if (!status) {
DEBUG(printk(KERN_INFO
"qla82xx_restart_isp(%ld): succeeded.\n",
vha->host_no));
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
if (vp->vp_idx)
qla2x00_vp_abort_isp(vp);
}
} else {
qla_printk(KERN_INFO, ha,
"qla82xx_restart_isp: **** FAILED ****\n");
}
return status;
}
void void
qla81xx_update_fw_options(scsi_qla_host_t *vha) qla81xx_update_fw_options(scsi_qla_host_t *vha)
{ {
......
...@@ -37,7 +37,10 @@ qla2x00_poll(struct rsp_que *rsp) ...@@ -37,7 +37,10 @@ qla2x00_poll(struct rsp_que *rsp)
unsigned long flags; unsigned long flags;
struct qla_hw_data *ha = rsp->hw; struct qla_hw_data *ha = rsp->hw;
local_irq_save(flags); local_irq_save(flags);
ha->isp_ops->intr_handler(0, rsp); if (IS_QLA82XX(ha))
qla82xx_poll(0, rsp);
else
ha->isp_ops->intr_handler(0, rsp);
local_irq_restore(flags); local_irq_restore(flags);
} }
......
...@@ -506,7 +506,10 @@ qla2x00_req_pkt(struct scsi_qla_host *vha, struct req_que *req, ...@@ -506,7 +506,10 @@ qla2x00_req_pkt(struct scsi_qla_host *vha, struct req_que *req,
cnt = (uint16_t) cnt = (uint16_t)
RD_REG_DWORD(&reg->isp25mq.req_q_out); RD_REG_DWORD(&reg->isp25mq.req_q_out);
else { else {
if (IS_FWI2_CAPABLE(ha)) if (IS_QLA82XX(ha))
cnt = (uint16_t)RD_REG_DWORD(
&reg->isp82.req_q_out);
else if (IS_FWI2_CAPABLE(ha))
cnt = (uint16_t)RD_REG_DWORD( cnt = (uint16_t)RD_REG_DWORD(
&reg->isp24.req_q_out); &reg->isp24.req_q_out);
else else
...@@ -579,11 +582,29 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req) ...@@ -579,11 +582,29 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req)
req->ring_ptr++; req->ring_ptr++;
/* Set chip new ring index. */ /* Set chip new ring index. */
if (ha->mqenable) { if (IS_QLA82XX(ha)) {
uint32_t dbval = 0x04 | (ha->portnum << 5);
/* write, read and verify logic */
dbval = dbval | (req->id << 8) | (req->ring_index << 16);
if (ql2xdbwr)
qla82xx_wr_32(ha, ha->nxdb_wr_ptr, dbval);
else {
WRT_REG_DWORD(
(unsigned long __iomem *)ha->nxdb_wr_ptr,
dbval);
wmb();
while (RD_REG_DWORD(ha->nxdb_rd_ptr) != dbval) {
WRT_REG_DWORD((unsigned long __iomem *)
ha->nxdb_wr_ptr, dbval);
wmb();
}
}
} else if (ha->mqenable) {
/* Set chip new ring index. */
WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index); WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
RD_REG_DWORD(&ioreg->hccr); RD_REG_DWORD(&ioreg->hccr);
} } else {
else {
if (IS_FWI2_CAPABLE(ha)) { if (IS_FWI2_CAPABLE(ha)) {
WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index); WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in); RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
...@@ -604,7 +625,7 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req) ...@@ -604,7 +625,7 @@ qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req)
* *
* Returns the number of IOCB entries needed to store @dsds. * Returns the number of IOCB entries needed to store @dsds.
*/ */
static inline uint16_t inline uint16_t
qla24xx_calc_iocbs(uint16_t dsds) qla24xx_calc_iocbs(uint16_t dsds)
{ {
uint16_t iocbs; uint16_t iocbs;
...@@ -626,7 +647,7 @@ qla24xx_calc_iocbs(uint16_t dsds) ...@@ -626,7 +647,7 @@ qla24xx_calc_iocbs(uint16_t dsds)
* @cmd_pkt: Command type 3 IOCB * @cmd_pkt: Command type 3 IOCB
* @tot_dsds: Total number of segments to transfer * @tot_dsds: Total number of segments to transfer
*/ */
static inline void inline void
qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
uint16_t tot_dsds) uint16_t tot_dsds)
{ {
...@@ -931,24 +952,31 @@ qla2x00_start_iocbs(srb_t *sp) ...@@ -931,24 +952,31 @@ qla2x00_start_iocbs(srb_t *sp)
device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
/* Adjust ring index. */ if (IS_QLA82XX(ha)) {
req->ring_index++; qla82xx_start_iocbs(sp);
if (req->ring_index == req->length) {
req->ring_index = 0;
req->ring_ptr = req->ring;
} else
req->ring_ptr++;
/* Set chip new ring index. */
if (ha->mqenable) {
WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
RD_REG_DWORD(&ioreg->hccr);
} else if (IS_FWI2_CAPABLE(ha)) {
WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
} else { } else {
WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp), req->ring_index); /* Adjust ring index. */
RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp)); req->ring_index++;
if (req->ring_index == req->length) {
req->ring_index = 0;
req->ring_ptr = req->ring;
} else
req->ring_ptr++;
/* Set chip new ring index. */
if (ha->mqenable) {
WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
RD_REG_DWORD(&ioreg->hccr);
} else if (IS_QLA82XX(ha)) {
qla82xx_start_iocbs(sp);
} else if (IS_FWI2_CAPABLE(ha)) {
WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
} else {
WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp),
req->ring_index);
RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp));
}
} }
} }
......
...@@ -326,7 +326,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -326,7 +326,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
/* Setup to process RIO completion. */ /* Setup to process RIO completion. */
handle_cnt = 0; handle_cnt = 0;
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha))
goto skip_rio; goto skip_rio;
switch (mb[0]) { switch (mb[0]) {
case MBA_SCSI_COMPLETION: case MBA_SCSI_COMPLETION:
...@@ -544,7 +544,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -544,7 +544,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
if (IS_QLA2100(ha)) if (IS_QLA2100(ha))
break; break;
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha))
DEBUG2(printk("scsi(%ld): DCBX Completed -- %04x %04x " DEBUG2(printk("scsi(%ld): DCBX Completed -- %04x %04x "
"%04x\n", vha->host_no, mb[1], mb[2], mb[3])); "%04x\n", vha->host_no, mb[1], mb[2], mb[3]));
else else
...@@ -845,7 +845,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha, ...@@ -845,7 +845,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
qla2x00_sp_compl(ha, sp); qla2x00_sp_compl(ha, sp);
} else { } else {
DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion" DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion"
" handle(%d)\n", vha->host_no, req->id, index)); " handle(0x%x)\n", vha->host_no, req->id, index));
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Invalid ISP SCSI completion handle\n"); "Invalid ISP SCSI completion handle\n");
...@@ -1337,6 +1337,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -1337,6 +1337,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
handle = (uint32_t) LSW(sts->handle); handle = (uint32_t) LSW(sts->handle);
que = MSW(sts->handle); que = MSW(sts->handle);
req = ha->req_q_map[que]; req = ha->req_q_map[que];
/* Fast path completion. */ /* Fast path completion. */
if (comp_status == CS_COMPLETE && scsi_status == 0) { if (comp_status == CS_COMPLETE && scsi_status == 0) {
qla2x00_process_completed_request(vha, req, handle); qla2x00_process_completed_request(vha, req, handle);
...@@ -1806,6 +1807,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -1806,6 +1807,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
struct rsp_que *rsp) struct rsp_que *rsp)
{ {
struct sts_entry_24xx *pkt; struct sts_entry_24xx *pkt;
struct qla_hw_data *ha = vha->hw;
if (!vha->flags.online) if (!vha->flags.online)
return; return;
...@@ -1866,7 +1868,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -1866,7 +1868,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
} }
/* Adjust ring index */ /* Adjust ring index */
WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index); if (IS_QLA82XX(ha)) {
struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index);
} else
WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
} }
static void static void
...@@ -2169,6 +2175,11 @@ static struct qla_init_msix_entry msix_entries[3] = { ...@@ -2169,6 +2175,11 @@ static struct qla_init_msix_entry msix_entries[3] = {
{ "qla2xxx (multiq)", qla25xx_msix_rsp_q }, { "qla2xxx (multiq)", qla25xx_msix_rsp_q },
}; };
static struct qla_init_msix_entry qla82xx_msix_entries[2] = {
{ "qla2xxx (default)", qla82xx_msix_default },
{ "qla2xxx (rsp_q)", qla82xx_msix_rsp_q },
};
static void static void
qla24xx_disable_msix(struct qla_hw_data *ha) qla24xx_disable_msix(struct qla_hw_data *ha)
{ {
...@@ -2195,7 +2206,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -2195,7 +2206,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
struct qla_msix_entry *qentry; struct qla_msix_entry *qentry;
entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count, entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count,
GFP_KERNEL); GFP_KERNEL);
if (!entries) if (!entries)
return -ENOMEM; return -ENOMEM;
...@@ -2240,8 +2251,15 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -2240,8 +2251,15 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
/* Enable MSI-X vectors for the base queue */ /* Enable MSI-X vectors for the base queue */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
qentry = &ha->msix_entries[i]; qentry = &ha->msix_entries[i];
ret = request_irq(qentry->vector, msix_entries[i].handler, if (IS_QLA82XX(ha)) {
0, msix_entries[i].name, rsp); ret = request_irq(qentry->vector,
qla82xx_msix_entries[i].handler,
0, qla82xx_msix_entries[i].name, rsp);
} else {
ret = request_irq(qentry->vector,
msix_entries[i].handler,
0, msix_entries[i].name, rsp);
}
if (ret) { if (ret) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"MSI-X: Unable to register handler -- %x/%d.\n", "MSI-X: Unable to register handler -- %x/%d.\n",
...@@ -2272,7 +2290,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -2272,7 +2290,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
/* If possible, enable MSI-X. */ /* If possible, enable MSI-X. */
if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
!IS_QLA8432(ha) && !IS_QLA8001(ha)) !IS_QLA8432(ha) && !IS_QLA8XXX_TYPE(ha))
goto skip_msi; goto skip_msi;
if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
...@@ -2302,7 +2320,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -2302,7 +2320,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
goto clear_risc_ints; goto clear_risc_ints;
} }
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"MSI-X: Falling back-to INTa mode -- %d.\n", ret); "MSI-X: Falling back-to MSI mode -- %d.\n", ret);
skip_msix: skip_msix:
if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
...@@ -2313,7 +2331,9 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -2313,7 +2331,9 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
if (!ret) { if (!ret) {
DEBUG2(qla_printk(KERN_INFO, ha, "MSI: Enabled.\n")); DEBUG2(qla_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
ha->flags.msi_enabled = 1; ha->flags.msi_enabled = 1;
} } else
qla_printk(KERN_WARNING, ha,
"MSI-X: Falling back-to INTa mode -- %d.\n", ret);
skip_msi: skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
...@@ -2331,7 +2351,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -2331,7 +2351,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
* FIXME: Noted that 8014s were being dropped during NK testing. * FIXME: Noted that 8014s were being dropped during NK testing.
* Timing deltas during MSI-X/INTa transitions? * Timing deltas during MSI-X/INTa transitions?
*/ */
if (IS_QLA81XX(ha)) if (IS_QLA81XX(ha) || IS_QLA82XX(ha))
goto fail; goto fail;
spin_lock_irq(&ha->hardware_lock); spin_lock_irq(&ha->hardware_lock);
if (IS_FWI2_CAPABLE(ha)) { if (IS_FWI2_CAPABLE(ha)) {
......
...@@ -49,6 +49,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -49,6 +49,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
if (ha->pdev->error_state > pci_channel_io_frozen) if (ha->pdev->error_state > pci_channel_io_frozen)
return QLA_FUNCTION_TIMEOUT; return QLA_FUNCTION_TIMEOUT;
if (vha->device_flags & DFLG_DEV_FAILED) {
DEBUG2_3_11(qla_printk(KERN_WARNING, ha,
"%s(%ld): Device in failed state, "
"timeout MBX Exiting.\n",
__func__, base_vha->host_no));
return QLA_FUNCTION_TIMEOUT;
}
reg = ha->iobase; reg = ha->iobase;
io_lock_on = base_vha->flags.init_done; io_lock_on = base_vha->flags.init_done;
...@@ -85,7 +93,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -85,7 +93,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
/* Load mailbox registers. */ /* Load mailbox registers. */
if (IS_FWI2_CAPABLE(ha)) if (IS_QLA82XX(ha))
optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
optr = (uint16_t __iomem *)&reg->isp24.mailbox0; optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
else else
optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0); optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
...@@ -133,7 +143,18 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -133,7 +143,18 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) { if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
if (IS_FWI2_CAPABLE(ha)) if (IS_QLA82XX(ha)) {
if (RD_REG_DWORD(&reg->isp82.hint) &
HINT_MBX_INT_PENDING) {
spin_unlock_irqrestore(&ha->hardware_lock,
flags);
DEBUG2_3_11(printk(KERN_INFO
"%s(%ld): Pending Mailbox timeout. "
"Exiting.\n", __func__, base_vha->host_no));
return QLA_FUNCTION_TIMEOUT;
}
WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
} else if (IS_FWI2_CAPABLE(ha))
WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT); WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
else else
WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT); WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
...@@ -147,7 +168,18 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -147,7 +168,18 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
base_vha->host_no, command)); base_vha->host_no, command));
if (IS_FWI2_CAPABLE(ha)) if (IS_QLA82XX(ha)) {
if (RD_REG_DWORD(&reg->isp82.hint) &
HINT_MBX_INT_PENDING) {
spin_unlock_irqrestore(&ha->hardware_lock,
flags);
DEBUG2_3_11(printk(KERN_INFO
"%s(%ld): Pending Mailbox timeout. "
"Exiting.\n", __func__, base_vha->host_no));
return QLA_FUNCTION_TIMEOUT;
}
WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
} else if (IS_FWI2_CAPABLE(ha))
WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT); WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
else else
WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT); WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
...@@ -264,7 +296,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ...@@ -264,7 +296,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
clear_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); clear_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
if (qla2x00_abort_isp(base_vha)) { if (ha->isp_ops->abort_isp(base_vha)) {
/* Failed. retry later. */ /* Failed. retry later. */
set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
} }
...@@ -952,7 +984,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, ...@@ -952,7 +984,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
mcp->mb[9] = vha->vp_idx; mcp->mb[9] = vha->vp_idx;
mcp->out_mb = MBX_9|MBX_0; mcp->out_mb = MBX_9|MBX_0;
mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
if (IS_QLA81XX(vha->hw)) if (IS_QLA8XXX_TYPE(vha->hw))
mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0; mcp->flags = 0;
...@@ -978,7 +1010,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, ...@@ -978,7 +1010,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n",
vha->host_no)); vha->host_no));
if (IS_QLA81XX(vha->hw)) { if (IS_QLA8XXX_TYPE(vha->hw)) {
vha->fcoe_vlan_id = mcp->mb[9] & 0xfff; vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
vha->fcoe_fcf_idx = mcp->mb[10]; vha->fcoe_fcf_idx = mcp->mb[10];
vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8; vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
...@@ -1076,6 +1108,10 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) ...@@ -1076,6 +1108,10 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n",
vha->host_no)); vha->host_no));
if (IS_QLA82XX(ha) && ql2xdbwr)
qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
(0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
if (ha->flags.npiv_supported) if (ha->flags.npiv_supported)
mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE; mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
else else
...@@ -1408,7 +1444,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha) ...@@ -1408,7 +1444,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha)
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
if (IS_QLA81XX(vha->hw)) { if (IS_QLA8XXX_TYPE(vha->hw)) {
/* Logout across all FCFs. */ /* Logout across all FCFs. */
mcp->mb[0] = MBC_LIP_FULL_LOGIN; mcp->mb[0] = MBC_LIP_FULL_LOGIN;
mcp->mb[1] = BIT_1; mcp->mb[1] = BIT_1;
...@@ -2797,7 +2833,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, ...@@ -2797,7 +2833,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
mcp->mb[0] = MBC_PORT_PARAMS; mcp->mb[0] = MBC_PORT_PARAMS;
mcp->mb[1] = loop_id; mcp->mb[1] = loop_id;
mcp->mb[2] = BIT_0; mcp->mb[2] = BIT_0;
if (IS_QLA81XX(vha->hw)) if (IS_QLA8XXX_TYPE(vha->hw))
mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0); mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
else else
mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
...@@ -3586,7 +3622,7 @@ qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma, ...@@ -3586,7 +3622,7 @@ qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
mbx_cmd_t mc; mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc; mbx_cmd_t *mcp = &mc;
if (!IS_QLA81XX(vha->hw)) if (!IS_QLA8XXX_TYPE(vha->hw))
return QLA_FUNCTION_FAILED; return QLA_FUNCTION_FAILED;
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
...@@ -3624,7 +3660,7 @@ qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma, ...@@ -3624,7 +3660,7 @@ qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
mbx_cmd_t mc; mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc; mbx_cmd_t *mcp = &mc;
if (!IS_QLA81XX(vha->hw)) if (!IS_QLA8XXX_TYPE(vha->hw))
return QLA_FUNCTION_FAILED; return QLA_FUNCTION_FAILED;
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
...@@ -3685,7 +3721,8 @@ qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data) ...@@ -3685,7 +3721,8 @@ qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
} }
int int
qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mresp) qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
uint16_t *mresp)
{ {
int rval; int rval;
mbx_cmd_t mc; mbx_cmd_t mc;
...@@ -3720,7 +3757,7 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t * ...@@ -3720,7 +3757,7 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *
mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15| mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
if (IS_QLA81XX(vha->hw)) if (IS_QLA8XXX_TYPE(vha->hw))
mcp->out_mb |= MBX_2; mcp->out_mb |= MBX_2;
mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
...@@ -3732,9 +3769,11 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t * ...@@ -3732,9 +3769,11 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
DEBUG2(printk(KERN_WARNING DEBUG2(printk(KERN_WARNING
"(%ld): failed=%x mb[0]=0x%x " "(%ld): failed=%x mb[0]=0x%x "
"mb[1]=0x%x mb[2]=0x%x mb[3]=0x%x mb[18]=0x%x mb[19]=0x%x. \n", vha->host_no, rval, "mb[1]=0x%x mb[2]=0x%x mb[3]=0x%x mb[18]=0x%x "
mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[18], mcp->mb[19])); "mb[19]=0x%x.\n",
vha->host_no, rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
mcp->mb[3], mcp->mb[18], mcp->mb[19]));
} else { } else {
DEBUG2(printk(KERN_WARNING DEBUG2(printk(KERN_WARNING
"scsi(%ld): done.\n", vha->host_no)); "scsi(%ld): done.\n", vha->host_no));
...@@ -3748,7 +3787,8 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t * ...@@ -3748,7 +3787,8 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *
} }
int int
qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mresp) qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
uint16_t *mresp)
{ {
int rval; int rval;
mbx_cmd_t mc; mbx_cmd_t mc;
...@@ -3760,9 +3800,10 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mres ...@@ -3760,9 +3800,10 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mres
memset(mcp->mb, 0 , sizeof(mcp->mb)); memset(mcp->mb, 0 , sizeof(mcp->mb));
mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */ mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha)) {
mcp->mb[1] |= BIT_15; mcp->mb[1] |= BIT_15;
mcp->mb[2] = IS_QLA81XX(ha) ? vha->fcoe_fcf_idx : 0; mcp->mb[2] = vha->fcoe_fcf_idx;
}
mcp->mb[16] = LSW(mreq->rcv_dma); mcp->mb[16] = LSW(mreq->rcv_dma);
mcp->mb[17] = MSW(mreq->rcv_dma); mcp->mb[17] = MSW(mreq->rcv_dma);
mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
...@@ -3777,13 +3818,13 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mres ...@@ -3777,13 +3818,13 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, uint16_t *mres
mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15| mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0; MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha))
mcp->out_mb |= MBX_2; mcp->out_mb |= MBX_2;
mcp->in_mb = MBX_0; mcp->in_mb = MBX_0;
if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
mcp->in_mb |= MBX_1; mcp->in_mb |= MBX_1;
if (IS_QLA81XX(ha)) if (IS_QLA8XXX_TYPE(ha))
mcp->in_mb |= MBX_3; mcp->in_mb |= MBX_3;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
...@@ -3875,7 +3916,8 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha) ...@@ -3875,7 +3916,8 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha)
if (!IS_FWI2_CAPABLE(ha)) if (!IS_FWI2_CAPABLE(ha))
return QLA_FUNCTION_FAILED; return QLA_FUNCTION_FAILED;
DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no)); DEBUG11(qla_printk(KERN_INFO, ha,
"%s(%ld): entered.\n", __func__, vha->host_no));
mcp->mb[0] = MBC_DATA_RATE; mcp->mb[0] = MBC_DATA_RATE;
mcp->mb[1] = 0; mcp->mb[1] = 0;
...@@ -3943,3 +3985,75 @@ qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, ...@@ -3943,3 +3985,75 @@ qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
return rval; return rval;
} }
int
qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
{
int rval;
struct qla_hw_data *ha = vha->hw;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
if (!IS_FWI2_CAPABLE(ha))
return QLA_FUNCTION_FAILED;
DEBUG11(qla_printk(KERN_INFO, ha,
"%s(%ld): entered.\n", __func__, vha->host_no));
memset(mcp, 0, sizeof(mbx_cmd_t));
mcp->mb[0] = MBC_TOGGLE_INTR;
mcp->mb[1] = 1;
mcp->out_mb = MBX_1|MBX_0;
mcp->in_mb = MBX_0;
mcp->tov = 30;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(qla_printk(KERN_WARNING, ha,
"%s(%ld): failed=%x mb[0]=%x.\n", __func__,
vha->host_no, rval, mcp->mb[0]));
} else {
DEBUG11(qla_printk(KERN_INFO, ha,
"%s(%ld): done.\n", __func__, vha->host_no));
}
return rval;
}
int
qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
{
int rval;
struct qla_hw_data *ha = vha->hw;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
if (!IS_QLA82XX(ha))
return QLA_FUNCTION_FAILED;
DEBUG11(qla_printk(KERN_INFO, ha,
"%s(%ld): entered.\n", __func__, vha->host_no));
memset(mcp, 0, sizeof(mbx_cmd_t));
mcp->mb[0] = MBC_TOGGLE_INTR;
mcp->mb[1] = 0;
mcp->out_mb = MBX_1|MBX_0;
mcp->in_mb = MBX_0;
mcp->tov = 30;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
DEBUG2_3_11(qla_printk(KERN_WARNING, ha,
"%s(%ld): failed=%x mb[0]=%x.\n", __func__,
vha->host_no, rval, mcp->mb[0]));
} else {
DEBUG11(qla_printk(KERN_INFO, ha,
"%s(%ld): done.\n", __func__, vha->host_no));
}
return rval;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册