Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2020-03-07 13:43:18 -08:00
22 changed files with 2800 additions and 1465 deletions
+118 -15
View File
@@ -1323,6 +1323,79 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
return count;
}
static ssize_t
qla2x00_beacon_config_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
struct qla_hw_data *ha = vha->hw;
uint16_t led[3] = { 0 };
if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return -EPERM;
if (ql26xx_led_config(vha, 0, led))
return scnprintf(buf, PAGE_SIZE, "\n");
return scnprintf(buf, PAGE_SIZE, "%#04hx %#04hx %#04hx\n",
led[0], led[1], led[2]);
}
static ssize_t
qla2x00_beacon_config_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
struct qla_hw_data *ha = vha->hw;
uint16_t options = BIT_0;
uint16_t led[3] = { 0 };
uint16_t word[4];
int n;
if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return -EPERM;
n = sscanf(buf, "%hx %hx %hx %hx", word+0, word+1, word+2, word+3);
if (n == 4) {
if (word[0] == 3) {
options |= BIT_3|BIT_2|BIT_1;
led[0] = word[1];
led[1] = word[2];
led[2] = word[3];
goto write;
}
return -EINVAL;
}
if (n == 2) {
/* check led index */
if (word[0] == 0) {
options |= BIT_2;
led[0] = word[1];
goto write;
}
if (word[0] == 1) {
options |= BIT_3;
led[1] = word[1];
goto write;
}
if (word[0] == 2) {
options |= BIT_1;
led[2] = word[1];
goto write;
}
return -EINVAL;
}
return -EINVAL;
write:
if (ql26xx_led_config(vha, options, led))
return -EFAULT;
return count;
}
static ssize_t
qla2x00_optrom_bios_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -2250,6 +2323,26 @@ qla2x00_port_no_show(struct device *dev, struct device_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "%u\n", vha->hw->port_no);
}
static ssize_t
qla2x00_dport_diagnostics_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
!IS_QLA28XX(vha->hw))
return scnprintf(buf, PAGE_SIZE, "\n");
if (!*vha->dport_data)
return scnprintf(buf, PAGE_SIZE, "\n");
return scnprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
vha->dport_data[0], vha->dport_data[1],
vha->dport_data[2], vha->dport_data[3]);
}
static DEVICE_ATTR(dport_diagnostics, 0444,
qla2x00_dport_diagnostics_show, NULL);
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL);
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -2264,6 +2357,8 @@ static DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
qla2x00_zio_timer_store);
static DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
qla2x00_beacon_store);
static DEVICE_ATTR(beacon_config, 0644, qla2x00_beacon_config_show,
qla2x00_beacon_config_store);
static DEVICE_ATTR(optrom_bios_version, S_IRUGO,
qla2x00_optrom_bios_version_show, NULL);
static DEVICE_ATTR(optrom_efi_version, S_IRUGO,
@@ -2327,6 +2422,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_zio,
&dev_attr_zio_timer,
&dev_attr_beacon,
&dev_attr_beacon_config,
&dev_attr_optrom_bios_version,
&dev_attr_optrom_efi_version,
&dev_attr_optrom_fcode_version,
@@ -2355,6 +2451,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_port_speed,
&dev_attr_port_no,
&dev_attr_fw_attr,
&dev_attr_dport_diagnostics,
NULL, /* reserve for qlini_mode */
NULL, /* reserve for ql2xiniexchg */
NULL, /* reserve for ql2xexchoffld */
@@ -2648,22 +2745,28 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (rval != QLA_SUCCESS)
goto done_free;
p->link_failure_count = stats->link_fail_cnt;
p->loss_of_sync_count = stats->loss_sync_cnt;
p->loss_of_signal_count = stats->loss_sig_cnt;
p->prim_seq_protocol_err_count = stats->prim_seq_err_cnt;
p->invalid_tx_word_count = stats->inval_xmit_word_cnt;
p->invalid_crc_count = stats->inval_crc_cnt;
p->link_failure_count = le32_to_cpu(stats->link_fail_cnt);
p->loss_of_sync_count = le32_to_cpu(stats->loss_sync_cnt);
p->loss_of_signal_count = le32_to_cpu(stats->loss_sig_cnt);
p->prim_seq_protocol_err_count = le32_to_cpu(stats->prim_seq_err_cnt);
p->invalid_tx_word_count = le32_to_cpu(stats->inval_xmit_word_cnt);
p->invalid_crc_count = le32_to_cpu(stats->inval_crc_cnt);
if (IS_FWI2_CAPABLE(ha)) {
p->lip_count = stats->lip_cnt;
p->tx_frames = stats->tx_frames;
p->rx_frames = stats->rx_frames;
p->dumped_frames = stats->discarded_frames;
p->nos_count = stats->nos_rcvd;
p->lip_count = le32_to_cpu(stats->lip_cnt);
p->tx_frames = le32_to_cpu(stats->tx_frames);
p->rx_frames = le32_to_cpu(stats->rx_frames);
p->dumped_frames = le32_to_cpu(stats->discarded_frames);
p->nos_count = le32_to_cpu(stats->nos_rcvd);
p->error_frames =
stats->dropped_frames + stats->discarded_frames;
p->rx_words = vha->qla_stats.input_bytes;
p->tx_words = vha->qla_stats.output_bytes;
le32_to_cpu(stats->dropped_frames) +
le32_to_cpu(stats->discarded_frames);
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
p->rx_words = le64_to_cpu(stats->fpm_recv_word_cnt);
p->tx_words = le64_to_cpu(stats->fpm_xmit_word_cnt);
} else {
p->rx_words = vha->qla_stats.input_bytes;
p->tx_words = vha->qla_stats.output_bytes;
}
}
p->fcp_control_requests = vha->qla_stats.control_requests;
p->fcp_input_requests = vha->qla_stats.input_requests;
@@ -2671,7 +2774,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
p->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20;
p->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20;
p->seconds_since_last_reset =
get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
do_div(p->seconds_since_last_reset, HZ);
done_free:
+21 -6
View File
@@ -32,6 +32,14 @@ static inline void bsg_job_done_backport(struct fc_bsg_job *job, int result,
#define bsg_job_done bsg_job_done_backport
#endif
static void qla2xxx_free_fcport_work(struct work_struct *work)
{
struct fc_port *fcport = container_of(work, typeof(*fcport),
free_work);
qla2x00_free_fcport(fcport);
}
/* BSG support for ELS/CT pass through */
void qla2x00_bsg_job_done(srb_t *sp, int res)
{
@@ -82,8 +90,10 @@ void qla2x00_bsg_sp_free(srb_t *sp)
if (sp->type == SRB_CT_CMD ||
sp->type == SRB_FXIOCB_BCMD ||
sp->type == SRB_ELS_CMD_HST)
qla2x00_free_fcport(sp->fcport);
sp->type == SRB_ELS_CMD_HST) {
INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work);
queue_work(ha->wq, &sp->fcport->free_work);
}
qla2x00_rel_sp(sp);
}
@@ -767,7 +777,7 @@ qla2x00_process_loopback(struct bsg_job *bsg_job)
uint16_t response[MAILBOX_REGISTER_COUNT];
uint16_t config[4], new_config[4];
uint8_t *fw_sts_ptr;
uint8_t *req_data = NULL;
void *req_data = NULL;
dma_addr_t req_data_dma;
uint32_t req_data_len;
uint8_t *rsp_data = NULL;
@@ -1591,10 +1601,15 @@ qla2x00_update_optrom(struct bsg_job *bsg_job)
bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
ha->optrom_region_size);
ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
ha->optrom_region_start, ha->optrom_region_size);
bsg_reply->result = DID_OK;
if (rval) {
bsg_reply->result = -EINVAL;
rval = -EINVAL;
} else {
bsg_reply->result = DID_OK;
}
vfree(ha->optrom_buffer);
ha->optrom_buffer = NULL;
ha->optrom_state = QLA_SWAITING;
@@ -2564,7 +2579,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
regions.global_image = active_regions.global;
if (IS_QLA28XX(ha)) {
qla27xx_get_active_image(vha, &active_regions);
qla28xx_get_aux_images(vha, &active_regions);
regions.board_config = active_regions.aux.board_config;
regions.vpd_nvram = active_regions.aux.vpd_nvram;
regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1;
-6
View File
@@ -2519,12 +2519,6 @@ qla83xx_fw_dump_failed:
/* Driver Debug Functions. */
/****************************************************************************/
static inline int
ql_mask_match(uint level)
{
return (level & ql2xextended_error_logging) == level;
}
/*
* This function is for formatting and logging debug information.
* It is to be used when vha is available. It formats the message
+6
View File
@@ -374,3 +374,9 @@ extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *,
struct qla_hw_data *);
extern int qla24xx_soft_reset(struct qla_hw_data *);
static inline int
ql_mask_match(uint level)
{
return (level & ql2xextended_error_logging) == level;
}
+282 -129
View File
@@ -141,7 +141,10 @@ typedef struct {
#define LSD(x) ((uint32_t)((uint64_t)(x)))
#define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
#define MAKE_HANDLE(x, y) ((uint32_t)((((uint32_t)(x)) << 16) | (uint32_t)(y)))
static inline uint32_t make_handle(uint16_t x, uint16_t y)
{
return ((uint32_t)x << 16) | y;
}
/*
* I/O register
@@ -436,7 +439,7 @@ struct els_logo_payload {
struct els_plogi_payload {
uint8_t opcode;
uint8_t rsvd[3];
uint8_t data[112];
__be32 data[112 / 4];
};
struct ct_arg {
@@ -619,9 +622,6 @@ typedef struct srb {
struct fc_port *fcport;
struct scsi_qla_host *vha;
unsigned int start_timer:1;
unsigned int abort:1;
unsigned int aborted:1;
unsigned int completed:1;
uint32_t handle;
uint16_t flags;
@@ -1075,6 +1075,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define MBA_TEMPERATURE_ALERT 0x8070 /* Temperature Alert */
#define MBA_DPORT_DIAGNOSTICS 0x8080 /* D-port Diagnostics */
#define MBA_TRANS_INSERT 0x8130 /* Transceiver Insertion */
#define MBA_TRANS_REMOVE 0x8131 /* Transceiver Removal */
#define MBA_FW_INIT_FAILURE 0x8401 /* Firmware initialization failure */
#define MBA_MIRROR_LUN_CHANGE 0x8402 /* Mirror LUN State Change
Notification */
@@ -1160,6 +1161,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define MBC_GET_FIRMWARE_OPTION 0x28 /* Get Firmware Options. */
#define MBC_GET_MEM_OFFLOAD_CNTRL_STAT 0x34 /* Memory Offload ctrl/Stat*/
#define MBC_SET_FIRMWARE_OPTION 0x38 /* Set Firmware Options. */
#define MBC_SET_GET_FC_LED_CONFIG 0x3b /* Set/Get FC LED config */
#define MBC_LOOP_PORT_BYPASS 0x40 /* Loop Port Bypass. */
#define MBC_LOOP_PORT_ENABLE 0x41 /* Loop Port Enable. */
#define MBC_GET_RESOURCE_COUNTS 0x42 /* Get Resource Counts. */
@@ -1286,10 +1288,15 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define MBX_1 BIT_1
#define MBX_0 BIT_0
#define RNID_TYPE_ELS_CMD 0x5
#define RNID_TYPE_PORT_LOGIN 0x7
#define RNID_BUFFER_CREDITS 0x8
#define RNID_TYPE_SET_VERSION 0x9
#define RNID_TYPE_ASIC_TEMP 0xC
#define ELS_CMD_MAP_SIZE 32
#define ELS_COMMAND_RDP 0x18
/*
* Firmware state codes from get firmware state mailbox command
*/
@@ -1500,47 +1507,44 @@ typedef struct {
#define GLSO_USE_DID BIT_3
struct link_statistics {
uint32_t link_fail_cnt;
uint32_t loss_sync_cnt;
uint32_t loss_sig_cnt;
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
uint32_t lip_cnt;
uint32_t link_up_cnt;
uint32_t link_down_loop_init_tmo;
uint32_t link_down_los;
uint32_t link_down_loss_rcv_clk;
__le32 link_fail_cnt;
__le32 loss_sync_cnt;
__le32 loss_sig_cnt;
__le32 prim_seq_err_cnt;
__le32 inval_xmit_word_cnt;
__le32 inval_crc_cnt;
__le32 lip_cnt;
__le32 link_up_cnt;
__le32 link_down_loop_init_tmo;
__le32 link_down_los;
__le32 link_down_loss_rcv_clk;
uint32_t reserved0[5];
uint32_t port_cfg_chg;
__le32 port_cfg_chg;
uint32_t reserved1[11];
uint32_t rsp_q_full;
uint32_t atio_q_full;
uint32_t drop_ae;
uint32_t els_proto_err;
uint32_t reserved2;
uint32_t tx_frames;
uint32_t rx_frames;
uint32_t discarded_frames;
uint32_t dropped_frames;
__le32 rsp_q_full;
__le32 atio_q_full;
__le32 drop_ae;
__le32 els_proto_err;
__le32 reserved2;
__le32 tx_frames;
__le32 rx_frames;
__le32 discarded_frames;
__le32 dropped_frames;
uint32_t reserved3;
uint32_t nos_rcvd;
__le32 nos_rcvd;
uint32_t reserved4[4];
uint32_t tx_prjt;
uint32_t rcv_exfail;
uint32_t rcv_abts;
uint32_t seq_frm_miss;
uint32_t corr_err;
uint32_t mb_rqst;
uint32_t nport_full;
uint32_t eofa;
__le32 tx_prjt;
__le32 rcv_exfail;
__le32 rcv_abts;
__le32 seq_frm_miss;
__le32 corr_err;
__le32 mb_rqst;
__le32 nport_full;
__le32 eofa;
uint32_t reserved5;
uint32_t fpm_recv_word_cnt_lo;
uint32_t fpm_recv_word_cnt_hi;
uint32_t fpm_disc_word_cnt_lo;
uint32_t fpm_disc_word_cnt_hi;
uint32_t fpm_xmit_word_cnt_lo;
uint32_t fpm_xmit_word_cnt_hi;
__le64 fpm_recv_word_cnt;
__le64 fpm_disc_word_cnt;
__le64 fpm_xmit_word_cnt;
uint32_t reserved6[70];
};
@@ -2651,10 +2655,11 @@ static const char * const port_dstate_str[] = {
#define GFF_ID_RSP_SIZE (16 + 128)
/*
* HBA attribute types.
* FDMI HBA attribute types.
*/
#define FDMI_HBA_ATTR_COUNT 9
#define FDMIV2_HBA_ATTR_COUNT 17
#define FDMI1_HBA_ATTR_COUNT 9
#define FDMI2_HBA_ATTR_COUNT 17
#define FDMI_HBA_NODE_NAME 0x1
#define FDMI_HBA_MANUFACTURER 0x2
#define FDMI_HBA_SERIAL_NUMBER 0x3
@@ -2666,12 +2671,13 @@ static const char * const port_dstate_str[] = {
#define FDMI_HBA_FIRMWARE_VERSION 0x9
#define FDMI_HBA_OS_NAME_AND_VERSION 0xa
#define FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH 0xb
#define FDMI_HBA_NODE_SYMBOLIC_NAME 0xc
#define FDMI_HBA_VENDOR_ID 0xd
#define FDMI_HBA_VENDOR_SPECIFIC_INFO 0xd
#define FDMI_HBA_NUM_PORTS 0xe
#define FDMI_HBA_FABRIC_NAME 0xf
#define FDMI_HBA_BOOT_BIOS_NAME 0x10
#define FDMI_HBA_TYPE_VENDOR_IDENTIFIER 0xe0
#define FDMI_HBA_VENDOR_IDENTIFIER 0xe0
struct ct_fdmi_hba_attr {
uint16_t type;
@@ -2688,31 +2694,9 @@ struct ct_fdmi_hba_attr {
uint8_t fw_version[32];
uint8_t os_version[128];
uint32_t max_ct_len;
} a;
};
struct ct_fdmi_hba_attributes {
uint32_t count;
struct ct_fdmi_hba_attr entry[FDMI_HBA_ATTR_COUNT];
};
struct ct_fdmiv2_hba_attr {
uint16_t type;
uint16_t len;
union {
uint8_t node_name[WWN_SIZE];
uint8_t manufacturer[64];
uint8_t serial_num[32];
uint8_t model[16+1];
uint8_t model_desc[80];
uint8_t hw_version[16];
uint8_t driver_version[32];
uint8_t orom_version[16];
uint8_t fw_version[32];
uint8_t os_version[128];
uint32_t max_ct_len;
uint8_t sym_name[256];
uint32_t vendor_id;
uint32_t vendor_specific_info;
uint32_t num_ports;
uint8_t fabric_name[WWN_SIZE];
uint8_t bios_name[32];
@@ -2720,22 +2704,30 @@ struct ct_fdmiv2_hba_attr {
} a;
};
struct ct_fdmiv2_hba_attributes {
struct ct_fdmi1_hba_attributes {
uint32_t count;
struct ct_fdmiv2_hba_attr entry[FDMIV2_HBA_ATTR_COUNT];
struct ct_fdmi_hba_attr entry[FDMI1_HBA_ATTR_COUNT];
};
struct ct_fdmi2_hba_attributes {
uint32_t count;
struct ct_fdmi_hba_attr entry[FDMI2_HBA_ATTR_COUNT];
};
/*
* Port attribute types.
* FDMI Port attribute types.
*/
#define FDMI_PORT_ATTR_COUNT 6
#define FDMIV2_PORT_ATTR_COUNT 16
#define FDMI1_PORT_ATTR_COUNT 6
#define FDMI2_PORT_ATTR_COUNT 16
#define FDMI2_SMARTSAN_PORT_ATTR_COUNT 23
#define FDMI_PORT_FC4_TYPES 0x1
#define FDMI_PORT_SUPPORT_SPEED 0x2
#define FDMI_PORT_CURRENT_SPEED 0x3
#define FDMI_PORT_MAX_FRAME_SIZE 0x4
#define FDMI_PORT_OS_DEVICE_NAME 0x5
#define FDMI_PORT_HOST_NAME 0x6
#define FDMI_PORT_NODE_NAME 0x7
#define FDMI_PORT_NAME 0x8
#define FDMI_PORT_SYM_NAME 0x9
@@ -2745,7 +2737,15 @@ struct ct_fdmiv2_hba_attributes {
#define FDMI_PORT_FC4_TYPE 0xd
#define FDMI_PORT_STATE 0x101
#define FDMI_PORT_COUNT 0x102
#define FDMI_PORT_ID 0x103
#define FDMI_PORT_IDENTIFIER 0x103
#define FDMI_SMARTSAN_SERVICE 0xF100
#define FDMI_SMARTSAN_GUID 0xF101
#define FDMI_SMARTSAN_VERSION 0xF102
#define FDMI_SMARTSAN_PROD_NAME 0xF103
#define FDMI_SMARTSAN_PORT_INFO 0xF104
#define FDMI_SMARTSAN_QOS_SUPPORT 0xF105
#define FDMI_SMARTSAN_SECURITY_SUPPORT 0xF106
#define FDMI_PORT_SPEED_1GB 0x1
#define FDMI_PORT_SPEED_2GB 0x2
@@ -2761,37 +2761,6 @@ struct ct_fdmiv2_hba_attributes {
#define FC_CLASS_3 0x08
#define FC_CLASS_2_3 0x0C
struct ct_fdmiv2_port_attr {
uint16_t type;
uint16_t len;
union {
uint8_t fc4_types[32];
uint32_t sup_speed;
uint32_t cur_speed;
uint32_t max_frame_size;
uint8_t os_dev_name[32];
uint8_t host_name[256];
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
uint8_t port_sym_name[128];
uint32_t port_type;
uint32_t port_supported_cos;
uint8_t fabric_name[WWN_SIZE];
uint8_t port_fc4_type[32];
uint32_t port_state;
uint32_t num_ports;
uint32_t port_id;
} a;
};
/*
* Port Attribute Block.
*/
struct ct_fdmiv2_port_attributes {
uint32_t count;
struct ct_fdmiv2_port_attr entry[FDMIV2_PORT_ATTR_COUNT];
};
struct ct_fdmi_port_attr {
uint16_t type;
uint16_t len;
@@ -2802,14 +2771,49 @@ struct ct_fdmi_port_attr {
uint32_t max_frame_size;
uint8_t os_dev_name[32];
uint8_t host_name[256];
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
uint8_t port_sym_name[128];
uint32_t port_type;
uint32_t port_supported_cos;
uint8_t fabric_name[WWN_SIZE];
uint8_t port_fc4_type[32];
uint32_t port_state;
uint32_t num_ports;
uint32_t port_id;
uint8_t smartsan_service[24];
uint8_t smartsan_guid[16];
uint8_t smartsan_version[24];
uint8_t smartsan_prod_name[16];
uint32_t smartsan_port_info;
uint32_t smartsan_qos_support;
uint32_t smartsan_security_support;
} a;
};
struct ct_fdmi_port_attributes {
struct ct_fdmi1_port_attributes {
uint32_t count;
struct ct_fdmi_port_attr entry[FDMI_PORT_ATTR_COUNT];
struct ct_fdmi_port_attr entry[FDMI1_PORT_ATTR_COUNT];
};
struct ct_fdmi2_port_attributes {
uint32_t count;
struct ct_fdmi_port_attr entry[FDMI2_PORT_ATTR_COUNT];
};
#define FDMI_ATTR_TYPELEN(obj) \
(sizeof((obj)->type) + sizeof((obj)->len))
#define FDMI_ATTR_ALIGNMENT(len) \
(4 - ((len) & 3))
/* FDMI register call options */
#define CALLOPT_FDMI1 0
#define CALLOPT_FDMI2 1
#define CALLOPT_FDMI2_SMARTSAN 2
/* FDMI definitions. */
#define GRHL_CMD 0x100
#define GHAT_CMD 0x101
@@ -2820,10 +2824,13 @@ struct ct_fdmi_port_attributes {
#define RHBA_RSP_SIZE 16
#define RHAT_CMD 0x201
#define RPRT_CMD 0x210
#define RPRT_RSP_SIZE 24
#define RPA_CMD 0x211
#define RPA_RSP_SIZE 16
#define SMARTSAN_RPA_RSP_SIZE 24
#define DHBA_CMD 0x300
#define DHBA_REQ_SIZE (16 + 8)
@@ -2906,30 +2913,24 @@ struct ct_sns_req {
uint8_t hba_identifier[8];
uint32_t entry_count;
uint8_t port_name[8];
struct ct_fdmi_hba_attributes attrs;
struct ct_fdmi2_hba_attributes attrs;
} rhba;
struct {
uint8_t hba_identifier[8];
uint32_t entry_count;
uint8_t port_name[8];
struct ct_fdmiv2_hba_attributes attrs;
} rhba2;
struct {
uint8_t hba_identifier[8];
struct ct_fdmi_hba_attributes attrs;
struct ct_fdmi1_hba_attributes attrs;
} rhat;
struct {
uint8_t port_name[8];
struct ct_fdmi_port_attributes attrs;
struct ct_fdmi2_port_attributes attrs;
} rpa;
struct {
uint8_t hba_identifier[8];
uint8_t port_name[8];
struct ct_fdmiv2_port_attributes attrs;
} rpa2;
struct ct_fdmi2_port_attributes attrs;
} rprt;
struct {
uint8_t port_name[8];
@@ -3043,7 +3044,7 @@ struct ct_sns_rsp {
struct {
uint32_t entry_count;
uint8_t port_name[8];
struct ct_fdmi_hba_attributes attrs;
struct ct_fdmi1_hba_attributes attrs;
} ghat;
struct {
@@ -3277,6 +3278,7 @@ struct isp_operations {
#define QLA_MSIX_RSP_Q 0x01
#define QLA_ATIO_VECTOR 0x02
#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x03
#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS 0x04
#define QLA_MIDX_DEFAULT 0
#define QLA_MIDX_RSP_Q 1
@@ -3589,6 +3591,134 @@ struct qlfc_fw {
uint32_t len;
};
struct rdp_req_payload {
uint32_t els_request;
uint32_t desc_list_len;
/* NPIV descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint8_t reserved;
uint8_t nport_id[3];
} npiv_desc;
};
struct rdp_rsp_payload {
struct {
uint32_t cmd;
uint32_t len;
} hdr;
/* LS Request Info descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint32_t req_payload_word_0;
} ls_req_info_desc;
/* LS Request Info descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint32_t req_payload_word_0;
} ls_req_info_desc2;
/* SFP diagnostic param descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint16_t temperature;
uint16_t vcc;
uint16_t tx_bias;
uint16_t tx_power;
uint16_t rx_power;
uint16_t sfp_flags;
} sfp_diag_desc;
/* Port Speed Descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint16_t speed_capab;
uint16_t operating_speed;
} port_speed_desc;
/* Link Error Status Descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint32_t link_fail_cnt;
uint32_t loss_sync_cnt;
uint32_t loss_sig_cnt;
uint32_t prim_seq_err_cnt;
uint32_t inval_xmit_word_cnt;
uint32_t inval_crc_cnt;
uint8_t pn_port_phy_type;
uint8_t reserved[3];
} ls_err_desc;
/* Port name description with diag param */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint8_t WWNN[WWN_SIZE];
uint8_t WWPN[WWN_SIZE];
} port_name_diag_desc;
/* Port Name desc for Direct attached Fx_Port or Nx_Port */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint8_t WWNN[WWN_SIZE];
uint8_t WWPN[WWN_SIZE];
} port_name_direct_desc;
/* Buffer Credit descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint32_t fcport_b2b;
uint32_t attached_fcport_b2b;
uint32_t fcport_rtt;
} buffer_credit_desc;
/* Optical Element Data Descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint16_t high_alarm;
uint16_t low_alarm;
uint16_t high_warn;
uint16_t low_warn;
uint32_t element_flags;
} optical_elmt_desc[5];
/* Optical Product Data Descriptor */
struct {
uint32_t desc_tag;
uint32_t desc_len;
uint8_t vendor_name[16];
uint8_t part_number[16];
uint8_t serial_number[16];
uint8_t revision[4];
uint8_t date[8];
} optical_prod_desc;
};
#define RDP_DESC_LEN(obj) \
(sizeof(obj) - sizeof((obj).desc_tag) - sizeof((obj).desc_len))
#define RDP_PORT_SPEED_1GB BIT_15
#define RDP_PORT_SPEED_2GB BIT_14
#define RDP_PORT_SPEED_4GB BIT_13
#define RDP_PORT_SPEED_10GB BIT_12
#define RDP_PORT_SPEED_8GB BIT_11
#define RDP_PORT_SPEED_16GB BIT_10
#define RDP_PORT_SPEED_32GB BIT_9
#define RDP_PORT_SPEED_64GB BIT_8
#define RDP_PORT_SPEED_UNKNOWN BIT_0
struct scsi_qlt_host {
void *target_lport_ptr;
struct mutex tgt_mutex;
@@ -3700,8 +3830,8 @@ struct qla_hw_data {
uint32_t fw_started:1;
uint32_t fw_init_done:1;
uint32_t detected_lr_sfp:1;
uint32_t using_lr_setting:1;
uint32_t lr_detected:1;
uint32_t rida_fmt2:1;
uint32_t purge_mbox:1;
uint32_t n2n_bigger:1;
@@ -3710,7 +3840,7 @@ struct qla_hw_data {
} flags;
uint16_t max_exchg;
uint16_t long_range_distance; /* 32G & above */
uint16_t lr_distance; /* 32G & above */
#define LR_DISTANCE_5K 1
#define LR_DISTANCE_10K 0
@@ -3992,6 +4122,8 @@ struct qla_hw_data {
#define SFP_DEV_SIZE 512
#define SFP_BLOCK_SIZE 64
#define SFP_RTDI_LEN SFP_BLOCK_SIZE
void *sfp_data;
dma_addr_t sfp_data_dma;
@@ -4371,6 +4503,15 @@ struct active_regions {
#define QLA_SET_DATA_RATE_NOLR 1
#define QLA_SET_DATA_RATE_LR 2 /* Set speed and initiate LR */
struct purex_item {
struct list_head list;
struct scsi_qla_host *vha;
void (*process_item)(struct scsi_qla_host *vha, void *pkt);
struct {
uint8_t iocb[64];
} iocb;
};
/*
* Qlogic scsi host structure
*/
@@ -4451,6 +4592,8 @@ typedef struct scsi_qla_host {
#define ISP_ABORT_TO_ROM 33
#define VPORT_DELETE 34
#define PROCESS_PUREX_IOCB 63
unsigned long pci_flags;
#define PFLG_DISCONNECTED 0 /* PCI device removed */
#define PFLG_DRIVER_REMOVING 1 /* PCI driver .remove */
@@ -4488,6 +4631,7 @@ typedef struct scsi_qla_host {
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
uint8_t fabric_node_name[WWN_SIZE];
uint8_t fabric_port_name[WWN_SIZE];
struct nvme_fc_local_port *nvme_local_port;
struct completion nvme_del_done;
@@ -4558,6 +4702,11 @@ typedef struct scsi_qla_host {
uint16_t ql2xexchoffld;
uint16_t ql2xiniexchg;
struct purex_list {
struct list_head head;
spinlock_t lock;
} purex_list;
struct name_list_extended gnl;
/* Count of active session/fcport */
int fcport_count;
@@ -4567,6 +4716,7 @@ typedef struct scsi_qla_host {
uint8_t n2n_node_name[WWN_SIZE];
uint8_t n2n_port_name[WWN_SIZE];
uint16_t n2n_id;
__le16 dport_data[4];
struct list_head gpnid_list;
struct fab_scan scan;
@@ -4849,11 +4999,14 @@ struct sff_8247_a0 {
u8 resv2[128];
};
#define AUTO_DETECT_SFP_SUPPORT(_vha)\
(ql2xautodetectsfp && !_vha->vp_idx && \
(IS_QLA25XX(_vha->hw) || IS_QLA81XX(_vha->hw) ||\
IS_QLA83XX(_vha->hw) || IS_QLA27XX(_vha->hw) || \
IS_QLA28XX(_vha->hw)))
/* BPM -- Buffer Plus Management support. */
#define IS_BPM_CAPABLE(ha) \
(IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || \
IS_QLA27XX(ha) || IS_QLA28XX(ha))
#define IS_BPM_RANGE_CAPABLE(ha) \
(IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
#define IS_BPM_ENABLED(vha) \
(ql2xautodetectsfp && !vha->vp_idx && IS_BPM_CAPABLE(vha->hw))
#define FLASH_SEMAPHORE_REGISTER_ADDR 0x00101016
+5 -6
View File
@@ -134,11 +134,11 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
} else {
seq_puts(s, "FW Resource count\n\n");
seq_printf(s, "Original TGT exchg count[%d]\n", mb[1]);
seq_printf(s, "current TGT exchg count[%d]\n", mb[2]);
seq_printf(s, "original Initiator Exchange count[%d]\n", mb[3]);
seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[6]);
seq_printf(s, "Original IOCB count[%d]\n", mb[7]);
seq_printf(s, "Current IOCB count[%d]\n", mb[10]);
seq_printf(s, "Current TGT exchg count[%d]\n", mb[2]);
seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[3]);
seq_printf(s, "Original Initiator Exchange count[%d]\n", mb[6]);
seq_printf(s, "Current IOCB count[%d]\n", mb[7]);
seq_printf(s, "Original IOCB count[%d]\n", mb[10]);
seq_printf(s, "MAX VP count[%d]\n", mb[11]);
seq_printf(s, "MAX FCF count[%d]\n", mb[12]);
seq_printf(s, "Current free pageable XCB buffer cnt[%d]\n",
@@ -149,7 +149,6 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
mb[22]);
seq_printf(s, "Original Target fast XCB buffer cnt[%d]\n",
mb[23]);
}
return 0;
+157 -16
View File
@@ -43,6 +43,9 @@
#define PDO_FORCE_ADISC BIT_1
#define PDO_FORCE_PLOGI BIT_0
struct buffer_credit_24xx {
u32 parameter[28];
};
#define PORT_DATABASE_24XX_SIZE 64
struct port_database_24xx {
@@ -732,6 +735,48 @@ struct ct_entry_24xx {
struct dsd64 dsd[2];
};
/*
* ISP queue - PUREX IOCB entry structure definition
*/
#define PUREX_IOCB_TYPE 0x51 /* CT Pass Through IOCB entry */
struct purex_entry_24xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
uint8_t sys_define; /* System defined. */
uint8_t entry_status; /* Entry Status. */
uint16_t reserved1;
uint8_t vp_idx;
uint8_t reserved2;
uint16_t status_flags;
uint16_t nport_handle;
uint16_t frame_size;
uint16_t trunc_frame_size;
uint32_t rx_xchg_addr;
uint8_t d_id[3];
uint8_t r_ctl;
uint8_t s_id[3];
uint8_t cs_ctl;
uint8_t f_ctl[3];
uint8_t type;
uint16_t seq_cnt;
uint8_t df_ctl;
uint8_t seq_id;
uint16_t rx_id;
uint16_t ox_id;
uint32_t param;
uint8_t els_frame_payload[20];
};
/*
* ISP queue - ELS Pass-Through entry structure definition.
*/
@@ -744,9 +789,8 @@ struct els_entry_24xx {
uint32_t handle; /* System handle. */
uint16_t reserved_1;
uint16_t nport_handle; /* N_PORT handle. */
uint16_t comp_status; /* response only */
uint16_t nport_handle;
uint16_t tx_dsd_count;
@@ -761,7 +805,7 @@ struct els_entry_24xx {
uint8_t opcode;
uint8_t reserved_2;
uint8_t port_id[3];
uint8_t d_id[3];
uint8_t s_id[3];
uint16_t control_flags; /* Control flags. */
@@ -773,13 +817,24 @@ struct els_entry_24xx {
#define ECF_CLR_PASSTHRU_PEND BIT_12
#define ECF_INCL_FRAME_HDR BIT_11
__le32 rx_byte_count;
__le32 tx_byte_count;
union {
struct {
__le32 rx_byte_count;
__le32 tx_byte_count;
__le64 tx_address __packed; /* Data segment 0 address. */
__le32 tx_len; /* Data segment 0 length. */
__le64 rx_address __packed; /* Data segment 1 address. */
__le32 rx_len; /* Data segment 1 length. */
__le64 tx_address __packed; /* DSD 0 address. */
__le32 tx_len; /* DSD 0 length. */
__le64 rx_address __packed; /* DSD 1 address. */
__le32 rx_len; /* DSD 1 length. */
};
struct {
uint32_t total_byte_count;
uint32_t error_subcode_1;
uint32_t error_subcode_2;
uint32_t error_subcode_3;
};
};
};
struct els_sts_entry_24xx {
@@ -805,15 +860,16 @@ struct els_sts_entry_24xx {
uint8_t opcode;
uint8_t reserved_3;
uint8_t port_id[3];
uint8_t reserved_4;
uint16_t reserved_5;
uint8_t d_id[3];
uint8_t s_id[3];
uint16_t control_flags; /* Control flags. */
uint32_t total_byte_count;
uint32_t error_subcode_1;
uint32_t error_subcode_2;
uint32_t error_subcode_3;
uint32_t reserved_4[4];
};
/*
* ISP queue - Mailbox Command entry structure definition.
@@ -954,6 +1010,91 @@ struct abort_entry_24xx {
uint8_t reserved_2[12];
};
#define ABTS_RCV_TYPE 0x54
#define ABTS_RSP_TYPE 0x55
struct abts_entry_24xx {
uint8_t entry_type;
uint8_t entry_count;
uint8_t handle_count;
uint8_t entry_status;
uint32_t handle; /* type 0x55 only */
uint16_t comp_status; /* type 0x55 only */
uint16_t nport_handle; /* type 0x54 only */
uint16_t control_flags; /* type 0x55 only */
uint8_t vp_idx;
uint8_t sof_type; /* sof_type is upper nibble */
uint32_t rx_xch_addr;
uint8_t d_id[3];
uint8_t r_ctl;
uint8_t s_id[3];
uint8_t cs_ctl;
uint8_t f_ctl[3];
uint8_t type;
uint16_t seq_cnt;
uint8_t df_ctl;
uint8_t seq_id;
uint16_t rx_id;
uint16_t ox_id;
uint32_t param;
union {
struct {
uint32_t subcode3;
uint32_t rsvd;
uint32_t subcode1;
uint32_t subcode2;
} error;
struct {
uint16_t rsrvd1;
uint8_t last_seq_id;
uint8_t seq_id_valid;
uint16_t aborted_rx_id;
uint16_t aborted_ox_id;
uint16_t high_seq_cnt;
uint16_t low_seq_cnt;
} ba_acc;
struct {
uint8_t vendor_unique;
uint8_t explanation;
uint8_t reason;
} ba_rjt;
} payload;
uint32_t rx_xch_addr_to_abort;
} __packed;
/* ABTS payload explanation values */
#define BA_RJT_EXP_NO_ADDITIONAL 0
#define BA_RJT_EXP_INV_OX_RX_ID 3
#define BA_RJT_EXP_SEQ_ABORTED 5
/* ABTS payload reason values */
#define BA_RJT_RSN_INV_CMD_CODE 1
#define BA_RJT_RSN_LOGICAL_ERROR 3
#define BA_RJT_RSN_LOGICAL_BUSY 5
#define BA_RJT_RSN_PROTOCOL_ERROR 7
#define BA_RJT_RSN_UNABLE_TO_PERFORM 9
#define BA_RJT_RSN_VENDOR_SPECIFIC 0xff
/* FC_F values */
#define FC_TYPE_BLD 0x000 /* Basic link data */
#define FC_F_CTL_RSP_CNTXT 0x800000 /* Responder of exchange */
#define FC_F_CTL_LAST_SEQ 0x100000 /* Last sequence */
#define FC_F_CTL_END_SEQ 0x80000 /* Last sequence */
#define FC_F_CTL_SEQ_INIT 0x010000 /* Sequence initiative */
#define FC_ROUTING_BLD 0x80 /* Basic link data frame */
#define FC_R_CTL_BLD_BA_ACC 0x04 /* BA_ACC (basic accept) */
/*
* ISP I/O Register Set structure definitions.
*/
@@ -1737,9 +1878,8 @@ struct access_chip_rsp_84xx {
/* LR Distance bit positions */
#define LR_DIST_NV_POS 2
#define LR_DIST_NV_MASK 0xf
#define LR_DIST_FW_POS 12
#define LR_DIST_FW_SHIFT (LR_DIST_FW_POS - LR_DIST_NV_POS)
#define LR_DIST_FW_FIELD(x) ((x) << LR_DIST_FW_SHIFT & 0xf000)
/* FAC semaphore defines */
#define FAC_SEMAPHORE_UNLOCK 0
@@ -1894,6 +2034,7 @@ struct nvram_81xx {
* BIT 6-15 = Unused
*/
uint16_t enhanced_features;
uint16_t reserved_24[4];
/* Offset 416. */
+20 -3
View File
@@ -31,7 +31,7 @@ extern int qla24xx_nvram_config(struct scsi_qla_host *);
extern int qla81xx_nvram_config(struct scsi_qla_host *);
extern void qla2x00_update_fw_options(struct scsi_qla_host *);
extern void qla24xx_update_fw_options(scsi_qla_host_t *);
extern void qla81xx_update_fw_options(scsi_qla_host_t *);
extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *);
@@ -109,7 +109,7 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, u8 *, u8*,
void *, u8);
int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *);
int qla24xx_detect_sfp(scsi_qla_host_t *vha);
int qla24xx_detect_sfp(scsi_qla_host_t *);
int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
extern void qla28xx_get_aux_images(struct scsi_qla_host *,
@@ -142,6 +142,8 @@ extern int qlport_down_retry;
extern int ql2xplogiabsentdevice;
extern int ql2xloginretrycount;
extern int ql2xfdmienable;
extern int ql2xrdpenable;
extern int ql2xsmartsan;
extern int ql2xallocfwdump;
extern int ql2xextended_error_logging;
extern int ql2xiidmaenable;
@@ -230,6 +232,7 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt);
/*
* Global Functions in qla_mid.c source file.
@@ -357,6 +360,9 @@ qla2x00_init_firmware(scsi_qla_host_t *, uint16_t);
extern int
qla2x00_get_port_database(scsi_qla_host_t *, fc_port_t *, uint8_t);
extern int
qla24xx_get_port_database(scsi_qla_host_t *, u16, struct port_database_24xx *);
extern int
qla2x00_get_firmware_state(scsi_qla_host_t *, uint16_t *);
@@ -455,6 +461,13 @@ qla82xx_set_driver_version(scsi_qla_host_t *, char *);
extern int
qla25xx_set_driver_version(scsi_qla_host_t *, char *);
extern int
qla25xx_set_els_cmds_supported(scsi_qla_host_t *);
extern int
qla24xx_get_buffer_credits(scsi_qla_host_t *, struct buffer_credit_24xx *,
dma_addr_t);
extern int
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
uint16_t, uint16_t, uint16_t, uint16_t);
@@ -556,6 +569,8 @@ qla2x00_process_completed_request(struct scsi_qla_host *, struct req_que *,
uint32_t);
extern irqreturn_t
qla2xxx_msix_rsp_q(int irq, void *dev_id);
extern irqreturn_t
qla2xxx_msix_rsp_q_hs(int irq, void *dev_id);
fc_port_t *qla2x00_find_fcport_by_loopid(scsi_qla_host_t *, uint16_t);
fc_port_t *qla2x00_find_fcport_by_wwpn(scsi_qla_host_t *, u8 *, u8);
fc_port_t *qla2x00_find_fcport_by_nportid(scsi_qla_host_t *, port_id_t *, u8);
@@ -660,7 +675,7 @@ extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
extern int qla2x00_fdmi_register(scsi_qla_host_t *);
extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *, size_t);
extern size_t qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *, size_t);
extern int qla2x00_chk_ms_status(scsi_qla_host_t *, ms_iocb_entry_t *,
struct ct_sns_rsp *, const char *);
extern void qla2x00_async_iocb_timeout(void *data);
@@ -848,6 +863,7 @@ extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *);
extern int qla82xx_read_temperature(scsi_qla_host_t *);
extern int qla8044_read_temperature(scsi_qla_host_t *);
extern int qla2x00_read_sfp_dev(struct scsi_qla_host *, char *, int);
extern int ql26xx_led_config(scsi_qla_host_t *, uint16_t, uint16_t *);
/* BSG related functions */
#ifndef NEW_LIBFC_API
@@ -922,6 +938,7 @@ void qlt_remove_target_resources(struct qla_hw_data *);
void qlt_clr_qp_table(struct scsi_qla_host *vha);
void qlt_set_mode(struct scsi_qla_host *);
int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode);
extern void qla24xx_process_purex_list(struct purex_list *);
/* nvme.c */
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
+802 -961
View File
File diff suppressed because it is too large Load Diff
+101 -101
View File
@@ -1043,7 +1043,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
__func__, __LINE__, (u8 *)&wwn, id.b24);
wwnn = wwn_to_u64(e->node_name);
qla24xx_post_newsess_work(vha, &id, (u8 *)&wwn,
(u8 *)&wwnn, NULL, FC4_TYPE_UNKNOWN);
(u8 *)&wwnn, NULL, 0);
}
}
@@ -2219,10 +2219,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
/* Check for secure flash support */
if (IS_QLA28XX(ha)) {
if (RD_REG_DWORD(&reg->mailbox12) & BIT_0) {
ql_log(ql_log_info, vha, 0xffff, "Adapter is Secure\n");
if (RD_REG_DWORD(&reg->mailbox12) & BIT_0)
ha->flags.secure_adapter = 1;
}
ql_log(ql_log_info, vha, 0xffff, "Secure Adapter: %s\n",
(ha->flags.secure_adapter) ? "Yes" : "No");
}
@@ -2270,6 +2270,12 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_init, vha, 0x0078,
"Verifying loaded RISC code...\n");
/* If smartsan enabled then require fdmi and rdp enabled */
if (ql2xsmartsan) {
ql2xfdmienable = 1;
ql2xrdpenable = 1;
}
if (qla2x00_isp_firmware(vha) != QLA_SUCCESS) {
rval = ha->isp_ops->chip_diag(vha);
if (rval)
@@ -3544,53 +3550,77 @@ static void qla2xxx_print_sfp_info(struct scsi_qla_host *vha)
}
/*
* Return Code:
* QLA_SUCCESS: no action
* QLA_INTERFACE_ERROR: SFP is not there.
* QLA_FUNCTION_FAILED: detected New SFP
/**
* qla24xx_detect_sfp()
*
* @vha: adapter state pointer.
*
* @return
* 0 -- Configure firmware to use short-range settings -- normal
* buffer-to-buffer credits.
*
* 1 -- Configure firmware to use long-range settings -- extra
* buffer-to-buffer credits should be allocated with
* ha->lr_distance containing distance settings from NVRAM or SFP
* (if supported).
*/
int
qla24xx_detect_sfp(scsi_qla_host_t *vha)
{
int rc = QLA_SUCCESS;
int rc, used_nvram;
struct sff_8247_a0 *a;
struct qla_hw_data *ha = vha->hw;
struct nvram_81xx *nv = ha->nvram;
#define LR_DISTANCE_UNKNOWN 2
static const char * const types[] = { "Short", "Long" };
static const char * const lengths[] = { "(10km)", "(5km)", "" };
u8 ll = 0;
if (!AUTO_DETECT_SFP_SUPPORT(vha))
/* Seed with NVRAM settings. */
used_nvram = 0;
ha->flags.lr_detected = 0;
if (IS_BPM_RANGE_CAPABLE(ha) &&
(nv->enhanced_features & NEF_LR_DIST_ENABLE)) {
used_nvram = 1;
ha->flags.lr_detected = 1;
ha->lr_distance =
(nv->enhanced_features >> LR_DIST_NV_POS)
& LR_DIST_NV_MASK;
}
if (!IS_BPM_ENABLED(vha))
goto out;
/* Determine SR/LR capabilities of SFP/Transceiver. */
rc = qla2x00_read_sfp_dev(vha, NULL, 0);
if (rc)
goto out;
used_nvram = 0;
a = (struct sff_8247_a0 *)vha->hw->sfp_data;
qla2xxx_print_sfp_info(vha);
if (a->fc_ll_cc7 & FC_LL_VL || a->fc_ll_cc7 & FC_LL_L) {
/* long range */
ha->flags.detected_lr_sfp = 1;
ha->flags.lr_detected = 0;
ll = a->fc_ll_cc7;
if (ll & FC_LL_VL || ll & FC_LL_L) {
/* Long range, track length. */
ha->flags.lr_detected = 1;
if (a->length_km > 5 || a->length_100m > 50)
ha->long_range_distance = LR_DISTANCE_10K;
ha->lr_distance = LR_DISTANCE_10K;
else
ha->long_range_distance = LR_DISTANCE_5K;
if (ha->flags.detected_lr_sfp != ha->flags.using_lr_setting)
ql_dbg(ql_dbg_async, vha, 0x507b,
"Detected Long Range SFP.\n");
} else {
/* short range */
ha->flags.detected_lr_sfp = 0;
if (ha->flags.using_lr_setting)
ql_dbg(ql_dbg_async, vha, 0x5084,
"Detected Short Range SFP.\n");
ha->lr_distance = LR_DISTANCE_5K;
}
if (!vha->flags.init_done)
rc = QLA_SUCCESS;
out:
return rc;
ql_dbg(ql_dbg_async, vha, 0x507b,
"SFP detect: %s-Range SFP %s (nvr=%x ll=%x lr=%x lrd=%x).\n",
types[ha->flags.lr_detected],
ha->flags.lr_detected ? lengths[ha->lr_distance] :
lengths[LR_DISTANCE_UNKNOWN],
used_nvram, ll, ha->flags.lr_detected, ha->lr_distance);
return ha->flags.lr_detected;
}
/**
@@ -3608,6 +3638,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
unsigned long flags;
uint16_t fw_major_version;
int done_once = 0;
if (IS_P3P_TYPE(ha)) {
rval = ha->isp_ops->load_risc(vha, &srisc_address);
@@ -3628,6 +3659,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
qla81xx_mpi_sync(vha);
execute_fw_with_lr:
/* Load firmware sequences */
rval = ha->isp_ops->load_risc(vha, &srisc_address);
if (rval == QLA_SUCCESS) {
@@ -3649,7 +3681,15 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
rval = qla2x00_execute_fw(vha, srisc_address);
/* Retrieve firmware information. */
if (rval == QLA_SUCCESS) {
qla24xx_detect_sfp(vha);
/* Enable BPM support? */
if (!done_once++ && qla24xx_detect_sfp(vha)) {
ql_dbg(ql_dbg_init, vha, 0x00ca,
"Re-starting firmware -- BPM.\n");
/* Best-effort - re-init. */
ha->isp_ops->reset_chip(vha);
ha->isp_ops->chip_diag(vha);
goto execute_fw_with_lr;
}
if ((IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
IS_QLA28XX(ha)) &&
@@ -3708,6 +3748,10 @@ enable_82xx_npiv:
"ISP Firmware failed checksum.\n");
goto failed;
}
/* Enable PUREX PASSTHRU */
if (ql2xrdpenable)
qla25xx_set_els_cmds_supported(vha);
} else
goto failed;
@@ -3919,6 +3963,13 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_8;
}
if (ql2xrdpenable)
ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
/* Enable Async 8130/8131 events -- transceiver insertion/removal */
if (IS_BPM_RANGE_CAPABLE(ha))
ha->fw_options[3] |= BIT_10;
ql_dbg(ql_dbg_init, vha, 0x00e8,
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
@@ -5060,7 +5111,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
if (N2N_TOPO(ha)) {
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
/* borrowing */
u32 *bp, i, sz;
u32 *bp, sz;
memset(ha->init_cb, 0, ha->init_cb_size);
sz = min_t(int, sizeof(struct els_plogi_payload),
@@ -5068,13 +5119,12 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
rval = qla24xx_get_port_login_templ(vha,
ha->init_cb_dma, (void *)ha->init_cb, sz);
if (rval == QLA_SUCCESS) {
bp = (uint32_t *)ha->init_cb;
for (i = 0; i < sz/4 ; i++, bp++)
*bp = cpu_to_be32(*bp);
__be32 *q = &ha->plogi_els_payld.data[0];
memcpy(&ha->plogi_els_payld.data,
(void *)ha->init_cb,
sizeof(ha->plogi_els_payld.data));
bp = (uint32_t *)ha->init_cb;
cpu_to_be32_array(q, bp, sz / 4);
memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
} else {
ql_dbg(ql_dbg_init, vha, 0x00d1,
"PLOGI ELS param read fail.\n");
@@ -5097,6 +5147,7 @@ skip_login:
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
return QLA_FUNCTION_FAILED;
}
found_devs = 0;
@@ -5542,24 +5593,22 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
}
vha->device_flags |= SWITCH_FOUND;
rval = qla2x00_get_port_name(vha, loop_id, vha->fabric_port_name, 0);
if (rval != QLA_SUCCESS)
ql_dbg(ql_dbg_disc, vha, 0x20ff,
"Failed to get Fabric Port Name\n");
if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
rval = qla2x00_send_change_request(vha, 0x3, 0);
if (rval != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x121,
"Failed to enable receiving of RSCN requests: 0x%x.\n",
rval);
"Failed to enable receiving of RSCN requests: 0x%x.\n",
rval);
}
do {
qla2x00_mgmt_svr_login(vha);
/* FDMI support. */
if (ql2xfdmienable &&
test_and_clear_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags))
qla2x00_fdmi_register(vha);
/* Ensure we are logged into the SNS. */
loop_id = NPH_SNS_LID(ha);
rval = ha->isp_ops->fabric_login(vha, loop_id, 0xff, 0xff,
@@ -5571,6 +5620,12 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
return rval;
}
/* FDMI support. */
if (ql2xfdmienable &&
test_and_clear_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags))
qla2x00_fdmi_register(vha);
if (test_and_clear_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags)) {
if (qla2x00_rft_id(vha)) {
/* EMPTY */
@@ -5813,7 +5868,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
/* Bypass ports whose FCP-4 type is not FCP_SCSI */
if (ql2xgffidenable &&
(!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
new_fcport->fc4_type != 0))
continue;
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
@@ -6657,7 +6712,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
ha->flags.n2n_ae = 0;
ha->flags.lip_ae = 0;
ha->current_topology = 0;
ha->flags.fw_started = 0;
QLA_FW_STOPPED(ha);
ha->flags.fw_init_done = 0;
ha->chip_reset++;
ha->base_qpair->chip_reset = ha->chip_reset;
@@ -8664,61 +8719,6 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
return status;
}
void
qla81xx_update_fw_options(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
/* Hold status IOCBs until ABTS response received. */
if (ql2xfwholdabts)
ha->fw_options[3] |= BIT_12;
/* Set Retry FLOGI in case of P2P connection */
if (ha->operating_mode == P2P) {
ha->fw_options[2] |= BIT_3;
ql_dbg(ql_dbg_disc, vha, 0x2103,
"(%s): Setting FLOGI retry BIT in fw_options[2]: 0x%x\n",
__func__, ha->fw_options[2]);
}
/* Move PUREX, ABTS RX & RIDA to ATIOQ */
if (ql2xmvasynctoatio) {
if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha))
ha->fw_options[2] |= BIT_11;
else
ha->fw_options[2] &= ~BIT_11;
}
if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha)) {
/* FW auto send SCSI status during */
ha->fw_options[1] |= BIT_8;
ha->fw_options[10] |= (u16)SAM_STAT_BUSY << 8;
/* FW perform Exchange validation */
ha->fw_options[2] |= BIT_4;
} else {
ha->fw_options[1] &= ~BIT_8;
ha->fw_options[10] &= 0x00ff;
ha->fw_options[2] &= ~BIT_4;
}
if (ql2xetsenable) {
/* Enable ETS Burst. */
memset(ha->fw_options, 0, sizeof(ha->fw_options));
ha->fw_options[2] |= BIT_9;
}
ql_dbg(ql_dbg_init, vha, 0x00e9,
"%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
__func__, ha->fw_options[1], ha->fw_options[2],
ha->fw_options[3], vha->host->active_mode);
qla2x00_set_fw_options(vha, ha->fw_options);
}
/*
* qla24xx_get_fcp_prio
* Gets the fcp cmd priority value for the logged in port.
+22 -20
View File
@@ -530,7 +530,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
int_to_scsilun(lun, (struct scsi_lun *)&mrk24->lun);
host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
mrk24->vp_index = vha->vp_idx;
mrk24->handle = MAKE_HANDLE(req->id, mrk24->handle);
mrk24->handle = make_handle(req->id, mrk24->handle);
} else {
SET_TARGET_ID(ha, mrk->target, loop_id);
mrk->lun = cpu_to_le16((uint16_t)lun);
@@ -1661,7 +1661,7 @@ qla24xx_start_scsi(srb_t *sp)
req->cnt -= req_cnt;
cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
/* Zero out remaining portion of packet. */
/* tagged queuing modifier -- default is TSK_SIMPLE (0). */
@@ -1849,7 +1849,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
/* Fill-in common area */
cmd_pkt = (struct cmd_type_crc_2 *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
clr_ptr = (uint32_t *)cmd_pkt + 2;
memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
@@ -1981,7 +1981,7 @@ qla2xxx_start_scsi_mq(srb_t *sp)
req->cnt -= req_cnt;
cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
/* Zero out remaining portion of packet. */
/* tagged queuing modifier -- default is TSK_SIMPLE (0). */
@@ -2184,7 +2184,7 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
/* Fill-in common area */
cmd_pkt = (struct cmd_type_crc_2 *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
clr_ptr = (uint32_t *)cmd_pkt + 2;
memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
@@ -2368,6 +2368,8 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
struct srb_iocb *lio = &sp->u.iocb_cmd;
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
if (lio->u.logio.flags & SRB_LOGIN_PRLI_ONLY) {
logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
} else {
@@ -2495,7 +2497,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
tsk->entry_type = TSK_MGMT_IOCB_TYPE;
tsk->entry_count = 1;
tsk->handle = MAKE_HANDLE(req->id, tsk->handle);
tsk->handle = make_handle(req->id, tsk->handle);
tsk->nport_handle = cpu_to_le16(fcport->loop_id);
tsk->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
tsk->control_flags = cpu_to_le32(flags);
@@ -2690,9 +2692,9 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->rx_dsd_count = 0;
els_iocb->opcode = elsio->u.els_logo.els_cmd;
els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->port_id[1] = sp->fcport->d_id.b.area;
els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
els_iocb->d_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->d_id[1] = sp->fcport->d_id.b.area;
els_iocb->d_id[2] = sp->fcport->d_id.b.domain;
/* For SID the byte order is different than DID */
els_iocb->s_id[1] = vha->d_id.b.al_pa;
els_iocb->s_id[2] = vha->d_id.b.area;
@@ -2945,7 +2947,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
sp->fcport = fcport;
elsio->timeout = qla2x00_els_dcmd2_iocb_timeout;
init_completion(&elsio->u.els_plogi.comp);
if (wait)
sp->flags = SRB_WAKEUP_ON_COMP;
@@ -2955,7 +2956,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
elsio->u.els_plogi.tx_size = elsio->u.els_plogi.rx_size = DMA_POOL_SIZE;
ptr = elsio->u.els_plogi.els_plogi_pyld =
dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
dma_alloc_coherent(&ha->pdev->dev, elsio->u.els_plogi.tx_size,
&elsio->u.els_plogi.els_plogi_pyld_dma, GFP_KERNEL);
if (!elsio->u.els_plogi.els_plogi_pyld) {
@@ -2964,7 +2965,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
}
resp_ptr = elsio->u.els_plogi.els_resp_pyld =
dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
dma_alloc_coherent(&ha->pdev->dev, elsio->u.els_plogi.rx_size,
&elsio->u.els_plogi.els_resp_pyld_dma, GFP_KERNEL);
if (!elsio->u.els_plogi.els_resp_pyld) {
@@ -2988,6 +2989,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld,
sizeof(*elsio->u.els_plogi.els_plogi_pyld));
init_completion(&elsio->u.els_plogi.comp);
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
rval = QLA_FUNCTION_FAILED;
@@ -3040,9 +3042,9 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
sp->type == SRB_ELS_CMD_RPT ?
bsg_request->rqst_data.r_els.els_code :
bsg_request->rqst_data.h_els.command_code;
els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->port_id[1] = sp->fcport->d_id.b.area;
els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
els_iocb->d_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->d_id[1] = sp->fcport->d_id.b.area;
els_iocb->d_id[2] = sp->fcport->d_id.b.domain;
els_iocb->control_flags = 0;
els_iocb->rx_byte_count =
cpu_to_le32(bsg_job->reply_payload.payload_len);
@@ -3376,7 +3378,7 @@ sufficient_dsds:
}
cmd_pkt = (struct cmd_type_6 *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
/* Zero out remaining portion of packet. */
/* tagged queuing modifier -- default is TSK_SIMPLE (0). */
@@ -3447,7 +3449,7 @@ sufficient_dsds:
goto queuing_error;
cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
/* Zero out remaining portion of packet. */
/* tagged queuing modifier -- default is TSK_SIMPLE (0).*/
@@ -3552,7 +3554,7 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
memset(abt_iocb, 0, sizeof(struct abort_entry_24xx));
abt_iocb->entry_type = ABORT_IOCB_TYPE;
abt_iocb->entry_count = 1;
abt_iocb->handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
abt_iocb->handle = cpu_to_le32(make_handle(req->id, sp->handle));
if (sp->fcport) {
abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
@@ -3560,7 +3562,7 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
}
abt_iocb->handle_to_abort =
cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no,
cpu_to_le32(make_handle(aio->u.abt.req_que_no,
aio->u.abt.cmd_hndl));
abt_iocb->vp_index = vha->vp_idx;
abt_iocb->req_que_no = cpu_to_le16(aio->u.abt.req_que_no);
@@ -3927,7 +3929,7 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
}
cmd_pkt = (struct cmd_bidir *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
/* Zero out remaining portion of packet. */
/* tagged queuing modifier -- default is TSK_SIMPLE (0).*/
+267 -40
View File
@@ -43,6 +43,144 @@ const char *const port_state_str[] = {
"ONLINE"
};
static void qla24xx_purex_iocb(scsi_qla_host_t *vha, void *pkt,
void (*process_item)(struct scsi_qla_host *vha, void *pkt))
{
struct purex_list *list = &vha->purex_list;
struct purex_item *item;
ulong flags;
item = kzalloc(sizeof(*item), GFP_KERNEL);
if (!item) {
ql_log(ql_log_warn, vha, 0x5092,
">> Failed allocate purex list item.\n");
return;
}
item->vha = vha;
item->process_item = process_item;
memcpy(&item->iocb, pkt, sizeof(item->iocb));
spin_lock_irqsave(&list->lock, flags);
list_add_tail(&item->list, &list->head);
spin_unlock_irqrestore(&list->lock, flags);
set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
}
static void
qla24xx_process_abts(struct scsi_qla_host *vha, void *pkt)
{
struct abts_entry_24xx *abts = pkt;
struct qla_hw_data *ha = vha->hw;
struct els_entry_24xx *rsp_els;
struct abts_entry_24xx *abts_rsp;
dma_addr_t dma;
uint32_t fctl;
int rval;
ql_dbg(ql_dbg_init, vha, 0x0286, "%s: entered.\n", __func__);
ql_log(ql_log_warn, vha, 0x0287,
"Processing ABTS xchg=%#x oxid=%#x rxid=%#x seqid=%#x seqcnt=%#x\n",
abts->rx_xch_addr_to_abort, abts->ox_id, abts->rx_id,
abts->seq_id, abts->seq_cnt);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0287,
"-------- ABTS RCV -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0287,
(uint8_t *)abts, sizeof(*abts));
rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els), &dma,
GFP_KERNEL);
if (!rsp_els) {
ql_log(ql_log_warn, vha, 0x0287,
"Failed allocate dma buffer ABTS/ELS RSP.\n");
return;
}
/* terminate exchange */
memset(rsp_els, 0, sizeof(*rsp_els));
rsp_els->entry_type = ELS_IOCB_TYPE;
rsp_els->entry_count = 1;
rsp_els->nport_handle = ~0;
rsp_els->rx_xchg_address = abts->rx_xch_addr_to_abort;
rsp_els->control_flags = EPD_RX_XCHG;
ql_dbg(ql_dbg_init, vha, 0x0283,
"Sending ELS Response to terminate exchange %#x...\n",
abts->rx_xch_addr_to_abort);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0283,
"-------- ELS RSP -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0283,
(uint8_t *)rsp_els, sizeof(*rsp_els));
rval = qla2x00_issue_iocb(vha, rsp_els, dma, 0);
if (rval) {
ql_log(ql_log_warn, vha, 0x0288,
"%s: iocb failed to execute -> %x\n", __func__, rval);
} else if (rsp_els->comp_status) {
ql_log(ql_log_warn, vha, 0x0289,
"%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n",
__func__, rsp_els->comp_status,
rsp_els->error_subcode_1, rsp_els->error_subcode_2);
} else {
ql_dbg(ql_dbg_init, vha, 0x028a,
"%s: abort exchange done.\n", __func__);
}
/* send ABTS response */
abts_rsp = (void *)rsp_els;
memset(abts_rsp, 0, sizeof(*abts_rsp));
abts_rsp->entry_type = ABTS_RSP_TYPE;
abts_rsp->entry_count = 1;
abts_rsp->nport_handle = abts->nport_handle;
abts_rsp->vp_idx = abts->vp_idx;
abts_rsp->sof_type = abts->sof_type & 0xf0;
abts_rsp->rx_xch_addr = abts->rx_xch_addr;
abts_rsp->d_id[0] = abts->s_id[0];
abts_rsp->d_id[1] = abts->s_id[1];
abts_rsp->d_id[2] = abts->s_id[2];
abts_rsp->r_ctl = FC_ROUTING_BLD | FC_R_CTL_BLD_BA_ACC;
abts_rsp->s_id[0] = abts->d_id[0];
abts_rsp->s_id[1] = abts->d_id[1];
abts_rsp->s_id[2] = abts->d_id[2];
abts_rsp->cs_ctl = abts->cs_ctl;
/* include flipping bit23 in fctl */
fctl = ~(abts->f_ctl[2] | 0x7F) << 16 |
FC_F_CTL_LAST_SEQ | FC_F_CTL_END_SEQ | FC_F_CTL_SEQ_INIT;
abts_rsp->f_ctl[0] = fctl >> 0 & 0xff;
abts_rsp->f_ctl[1] = fctl >> 8 & 0xff;
abts_rsp->f_ctl[2] = fctl >> 16 & 0xff;
abts_rsp->type = FC_TYPE_BLD;
abts_rsp->rx_id = abts->rx_id;
abts_rsp->ox_id = abts->ox_id;
abts_rsp->payload.ba_acc.aborted_rx_id = abts->rx_id;
abts_rsp->payload.ba_acc.aborted_ox_id = abts->ox_id;
abts_rsp->payload.ba_acc.high_seq_cnt = ~0;
abts_rsp->rx_xch_addr_to_abort = abts->rx_xch_addr_to_abort;
ql_dbg(ql_dbg_init, vha, 0x028b,
"Sending BA ACC response to ABTS %#x...\n",
abts->rx_xch_addr_to_abort);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x028b,
"-------- ELS RSP -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x028b,
(uint8_t *)abts_rsp, sizeof(*abts_rsp));
rval = qla2x00_issue_iocb(vha, abts_rsp, dma, 0);
if (rval) {
ql_log(ql_log_warn, vha, 0x028c,
"%s: iocb failed to execute -> %x\n", __func__, rval);
} else if (abts_rsp->comp_status) {
ql_log(ql_log_warn, vha, 0x028d,
"%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n",
__func__, abts_rsp->comp_status,
abts_rsp->payload.error.subcode1,
abts_rsp->payload.error.subcode2);
} else {
ql_dbg(ql_dbg_init, vha, 0x028ea,
"%s: done.\n", __func__);
}
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), rsp_els, dma);
}
/**
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
* @irq: interrupt number
@@ -728,12 +866,24 @@ skip_rio:
break;
case MBA_SYSTEM_ERR: /* System Error */
mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
IS_QLA28XX(ha)) ?
RD_REG_WORD(&reg24->mailbox7) : 0;
ql_log(ql_log_warn, vha, 0x5003,
"ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
"mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
mbx = 0;
if (IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
u16 m[4];
m[0] = RD_REG_WORD(&reg24->mailbox4);
m[1] = RD_REG_WORD(&reg24->mailbox5);
m[2] = RD_REG_WORD(&reg24->mailbox6);
mbx = m[3] = RD_REG_WORD(&reg24->mailbox7);
ql_log(ql_log_warn, vha, 0x5003,
"ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh mbx4=%xh mbx5=%xh mbx6=%xh mbx7=%xh.\n",
mb[1], mb[2], mb[3], m[0], m[1], m[2], m[3]);
} else
ql_log(ql_log_warn, vha, 0x5003,
"ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n ",
mb[1], mb[2], mb[3]);
ha->fw_dump_mpi =
(IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&
RD_REG_WORD(&reg24->mailbox7) & BIT_8;
@@ -825,13 +975,15 @@ skip_rio:
"LOOP UP detected (%s Gbps).\n",
qla2x00_get_link_speed_str(ha, ha->link_data_rate));
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
if (mb[2] & BIT_0)
ql_log(ql_log_info, vha, 0x11a0,
"FEC=enabled (link up).\n");
}
vha->flags.management_server_logged_in = 0;
qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate);
if (AUTO_DETECT_SFP_SUPPORT(vha)) {
set_bit(DETECT_SFP_CHANGE, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
}
break;
case MBA_LOOP_DOWN: /* Loop Down Event */
@@ -1266,6 +1418,7 @@ global_port_update:
ql_dbg(ql_dbg_async, vha, 0x5052,
"D-Port Diagnostics: %04x %04x %04x %04x\n",
mb[0], mb[1], mb[2], mb[3]);
memcpy(vha->dport_data, mb, sizeof(vha->dport_data));
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
static char *results[] = {
"start", "done(pass)", "done(error)", "undefined" };
@@ -1303,6 +1456,11 @@ global_port_update:
case MBA_TRANS_INSERT:
ql_dbg(ql_dbg_async, vha, 0x5091,
"Transceiver Insertion: %04x\n", mb[1]);
set_bit(DETECT_SFP_CHANGE, &vha->dpc_flags);
break;
case MBA_TRANS_REMOVE:
ql_dbg(ql_dbg_async, vha, 0x5091, "Transceiver Removal\n");
break;
default:
@@ -1774,11 +1932,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
}
if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
ql_dbg(ql_dbg_async, fcport->vha, 0x5036,
"Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x "
"iop0=%x.\n", type, fcport->port_name, sp->handle,
fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa,
ql_dbg(ql_dbg_async, sp->vha, 0x5036,
"Async-%s complete: handle=%x pid=%06x wwpn=%8phC iop0=%x\n",
type, sp->handle, fcport->d_id.b24, fcport->port_name,
le32_to_cpu(logio->io_parameter[0]));
vha->hw->exch_starvation = 0;
@@ -1857,11 +2013,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
break;
}
ql_dbg(ql_dbg_async, fcport->vha, 0x5037,
"Async-%s failed - %8phC hdl=%x portid=%02x%02x%02x comp=%x "
"iop0=%x iop1=%x.\n", type, fcport->port_name,
sp->handle, fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa,
ql_dbg(ql_dbg_async, sp->vha, 0x5037,
"Async-%s failed: handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n",
type, sp->handle, fcport->d_id.b24, fcport->port_name,
le16_to_cpu(logio->comp_status),
le32_to_cpu(logio->io_parameter[0]),
le32_to_cpu(logio->io_parameter[1]));
@@ -1930,6 +2084,7 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
struct nvmefc_fcp_req *fd;
uint16_t ret = QLA_SUCCESS;
uint16_t comp_status = le16_to_cpu(sts->comp_status);
int logit = 0;
iocb = &sp->u.iocb_cmd;
fcport = sp->fcport;
@@ -1940,6 +2095,12 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
if (unlikely(iocb->u.nvme.aen_op))
atomic_dec(&sp->vha->hw->nvme_active_aen_cnt);
if (unlikely(comp_status != CS_COMPLETE))
logit = 1;
fd->transferred_length = fd->payload_length -
le32_to_cpu(sts->residual_len);
/*
* State flags: Bit 6 and 0.
* If 0 is set, we don't care about 6.
@@ -1950,8 +2111,20 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
*/
if (!(state_flags & (SF_FCP_RSP_DMA | SF_NVME_ERSP))) {
iocb->u.nvme.rsp_pyld_len = 0;
} else if ((state_flags & SF_FCP_RSP_DMA)) {
} else if ((state_flags & (SF_FCP_RSP_DMA | SF_NVME_ERSP)) ==
(SF_FCP_RSP_DMA | SF_NVME_ERSP)) {
/* Response already DMA'd to fd->rspaddr. */
iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len);
} else if ((state_flags & SF_FCP_RSP_DMA)) {
/*
* Non-zero value in first 12 bytes of NVMe_RSP IU, treat this
* as an error.
*/
iocb->u.nvme.rsp_pyld_len = 0;
fd->transferred_length = 0;
ql_dbg(ql_dbg_io, fcport->vha, 0x307a,
"Unexpected values in NVMe_RSP IU.\n");
logit = 1;
} else if (state_flags & SF_NVME_ERSP) {
uint32_t *inbuf, *outbuf;
uint16_t iter;
@@ -1959,19 +2132,43 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
inbuf = (uint32_t *)&sts->nvme_ersp_data;
outbuf = (uint32_t *)fd->rspaddr;
iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len);
if (unlikely(iocb->u.nvme.rsp_pyld_len >
sizeof(struct nvme_fc_ersp_iu))) {
if (ql_mask_match(ql_dbg_io)) {
WARN_ONCE(1, "Unexpected response payload length %u.\n",
iocb->u.nvme.rsp_pyld_len);
ql_log(ql_log_warn, fcport->vha, 0x5100,
"Unexpected response payload length %u.\n",
iocb->u.nvme.rsp_pyld_len);
}
iocb->u.nvme.rsp_pyld_len =
sizeof(struct nvme_fc_ersp_iu);
}
iter = iocb->u.nvme.rsp_pyld_len >> 2;
for (; iter; iter--)
*outbuf++ = swab32(*inbuf++);
} else { /* unhandled case */
ql_log(ql_log_warn, fcport->vha, 0x503a,
"NVME-%s error. Unhandled state_flags of %x\n",
sp->name, state_flags);
}
fd->transferred_length = fd->payload_length -
le32_to_cpu(sts->residual_len);
if (state_flags & SF_NVME_ERSP) {
struct nvme_fc_ersp_iu *rsp_iu = fd->rspaddr;
u32 tgt_xfer_len;
if (unlikely(comp_status != CS_COMPLETE))
tgt_xfer_len = be32_to_cpu(rsp_iu->xfrd_len);
if (fd->transferred_length != tgt_xfer_len) {
ql_dbg(ql_dbg_io, fcport->vha, 0x3079,
"Dropped frame(s) detected (sent/rcvd=%u/%u).\n",
tgt_xfer_len, fd->transferred_length);
logit = 1;
} else if (comp_status == CS_DATA_UNDERRUN) {
/*
* Do not log if this is just an underflow and there
* is no data loss.
*/
logit = 0;
}
}
if (unlikely(logit))
ql_log(ql_log_warn, fcport->vha, 0x5060,
"NVME-%s ERR Handling - hdl=%x status(%x) tr_len:%x resid=%x ox_id=%x\n",
sp->name, sp->handle, comp_status,
@@ -2528,11 +2725,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
return;
}
if (sp->abort)
sp->aborted = 1;
else
sp->completed = 1;
if (sp->cmd_type != TYPE_SRB) {
req->outstanding_cmds[handle] = NULL;
ql_dbg(ql_dbg_io, vha, 0x3015,
@@ -3095,6 +3287,11 @@ process_err:
qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
break;
case ABTS_RECV_24XX:
if (qla_ini_mode_enabled(vha)) {
qla24xx_purex_iocb(vha, pkt,
qla24xx_process_abts);
break;
}
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
IS_QLA28XX(ha)) {
/* ensure that the ATIO queue is empty */
@@ -3139,6 +3336,19 @@ process_err:
qla_ctrlvp_completed(vha, rsp->req,
(struct vp_ctrl_entry_24xx *)pkt);
break;
case PUREX_IOCB_TYPE:
{
struct purex_entry_24xx *purex = (void *)pkt;
if (purex->els_frame_payload[3] != ELS_COMMAND_RDP) {
ql_dbg(ql_dbg_init, vha, 0x5091,
"Discarding ELS Request opcode %#x...\n",
purex->els_frame_payload[3]);
break;
}
qla24xx_purex_iocb(vha, pkt, qla24xx_process_purex_rdp);
break;
}
default:
/* Type Not Supported. */
ql_dbg(ql_dbg_async, vha, 0x5042,
@@ -3451,6 +3661,25 @@ qla24xx_msix_default(int irq, void *dev_id)
irqreturn_t
qla2xxx_msix_rsp_q(int irq, void *dev_id)
{
struct qla_hw_data *ha;
struct qla_qpair *qpair;
qpair = dev_id;
if (!qpair) {
ql_log(ql_log_info, NULL, 0x505b,
"%s: NULL response queue pointer.\n", __func__);
return IRQ_NONE;
}
ha = qpair->hw;
queue_work(ha->wq, &qpair->q_work);
return IRQ_HANDLED;
}
irqreturn_t
qla2xxx_msix_rsp_q_hs(int irq, void *dev_id)
{
struct qla_hw_data *ha;
struct qla_qpair *qpair;
@@ -3465,13 +3694,10 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id)
}
ha = qpair->hw;
/* Clear the interrupt, if enabled, for this response queue */
if (unlikely(!ha->flags.disable_msix_handshake)) {
reg = &ha->iobase->isp24;
spin_lock_irqsave(&ha->hardware_lock, flags);
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
reg = &ha->iobase->isp24;
spin_lock_irqsave(&ha->hardware_lock, flags);
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
queue_work(ha->wq, &qpair->q_work);
@@ -3503,6 +3729,7 @@ static const struct qla_init_msix_entry msix_entries[] = {
{ "rsp_q", qla24xx_msix_rsp_q },
{ "atio_q", qla83xx_msix_atio_q },
{ "qpair_multiq", qla2xxx_msix_rsp_q },
{ "qpair_multiq_hs", qla2xxx_msix_rsp_q_hs },
};
static const struct qla_init_msix_entry qla82xx_msix_entries[] = {
+296 -92
View File
@@ -117,10 +117,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
if (ha->pdev->error_state > pci_channel_io_frozen) {
if (ha->pdev->error_state == pci_channel_io_perm_failure) {
ql_log(ql_log_warn, vha, 0x1001,
"error_state is greater than pci_channel_io_frozen, "
"exiting.\n");
"PCI channel failed permanently, exiting.\n");
return QLA_FUNCTION_TIMEOUT;
}
@@ -643,30 +642,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
return rval;
}
#define EXTENDED_BB_CREDITS BIT_0
#define NVME_ENABLE_FLAG BIT_3
static inline uint16_t qla25xx_set_sfp_lr_dist(struct qla_hw_data *ha)
{
uint16_t mb4 = BIT_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
mb4 |= ha->long_range_distance << LR_DIST_FW_POS;
return mb4;
}
static inline uint16_t qla25xx_set_nvr_lr_dist(struct qla_hw_data *ha)
{
uint16_t mb4 = BIT_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
struct nvram_81xx *nv = ha->nvram;
mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features);
}
return mb4;
}
/*
* qla2x00_execute_fw
@@ -690,10 +666,14 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
struct qla_hw_data *ha = vha->hw;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
u8 semaphore = 0;
#define EXE_FW_FORCE_SEMAPHORE BIT_7
u8 retry = 3;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
"Entered %s.\n", __func__);
again:
mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
mcp->out_mb = MBX_0;
mcp->in_mb = MBX_0;
@@ -703,25 +683,13 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
mcp->mb[3] = 0;
mcp->mb[4] = 0;
mcp->mb[11] = 0;
ha->flags.using_lr_setting = 0;
if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
if (ql2xautodetectsfp) {
if (ha->flags.detected_lr_sfp) {
mcp->mb[4] |=
qla25xx_set_sfp_lr_dist(ha);
ha->flags.using_lr_setting = 1;
}
} else {
struct nvram_81xx *nv = ha->nvram;
/* set LR distance if specified in nvram */
if (nv->enhanced_features &
NEF_LR_DIST_ENABLE) {
mcp->mb[4] |=
qla25xx_set_nvr_lr_dist(ha);
ha->flags.using_lr_setting = 1;
}
}
/* Enable BPM? */
if (ha->flags.lr_detected) {
mcp->mb[4] = BIT_0;
if (IS_BPM_RANGE_CAPABLE(ha))
mcp->mb[4] |=
ha->lr_distance << LR_DIST_FW_POS;
}
if (ql2xnvmeenable && (IS_QLA27XX(ha) || IS_QLA28XX(ha)))
@@ -747,6 +715,9 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
if (ha->flags.exchoffld_enabled)
mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
if (semaphore)
mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE;
mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11;
mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
} else {
@@ -763,6 +734,15 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
if (IS_QLA28XX(ha) && rval == QLA_COMMAND_ERROR &&
mcp->mb[1] == 0x27 && retry) {
semaphore = 1;
retry--;
ql_dbg(ql_dbg_async, vha, 0x1026,
"Exe FW: force semaphore.\n");
goto again;
}
ql_dbg(ql_dbg_mbx, vha, 0x1026,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
return rval;
@@ -1137,11 +1117,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];
ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];
if (IS_QLA28XX(ha)) {
if (mcp->mb[16] & BIT_10) {
ql_log(ql_log_info, vha, 0xffff,
"FW support secure flash updates\n");
if (mcp->mb[16] & BIT_10)
ha->flags.secure_fw = 1;
}
ql_log(ql_log_info, vha, 0xffff,
"Secure Flash Update in FW: %s\n",
(ha->flags.secure_fw) ? "Supported" :
"Not Supported");
}
}
@@ -1405,17 +1387,20 @@ qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
if (!vha->hw->flags.fw_started)
return QLA_INVALID_COMMAND;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
"Entered %s.\n", __func__);
mcp->mb[0] = MBC_IOCB_COMMAND_A64;
mcp->mb[1] = 0;
mcp->mb[2] = MSW(phys_addr);
mcp->mb[3] = LSW(phys_addr);
mcp->mb[2] = MSW(LSD(phys_addr));
mcp->mb[3] = LSW(LSD(phys_addr));
mcp->mb[6] = MSW(MSD(phys_addr));
mcp->mb[7] = LSW(MSD(phys_addr));
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_2|MBX_0;
mcp->in_mb = MBX_1|MBX_0;
mcp->tov = tov;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -1424,13 +1409,14 @@ qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
/*EMPTY*/
ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
} else {
sts_entry_t *sts_entry = (sts_entry_t *) buffer;
sts_entry_t *sts_entry = buffer;
/* Mask reserved bits. */
sts_entry->entry_status &=
IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
"Done %s.\n", __func__);
"Done %s (status=%x).\n", __func__,
sts_entry->entry_status);
}
return rval;
@@ -1475,7 +1461,7 @@ qla2x00_abort_command(srb_t *sp)
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
"Entered %s.\n", __func__);
if (vha->flags.qpairs_available && sp->qpair)
if (sp->qpair)
req = sp->qpair->req;
else
req = vha->req;
@@ -2045,6 +2031,57 @@ gpd_error_out:
return rval;
}
int
qla24xx_get_port_database(scsi_qla_host_t *vha, u16 nport_handle,
struct port_database_24xx *pdb)
{
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
dma_addr_t pdb_dma;
int rval;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1115,
"Entered %s.\n", __func__);
memset(pdb, 0, sizeof(*pdb));
pdb_dma = dma_map_single(&vha->hw->pdev->dev, pdb,
sizeof(*pdb), DMA_FROM_DEVICE);
if (!pdb_dma) {
ql_log(ql_log_warn, vha, 0x1116, "Failed to map dma buffer.\n");
return QLA_MEMORY_ALLOC_FAILED;
}
mcp->mb[0] = MBC_GET_PORT_DATABASE;
mcp->mb[1] = nport_handle;
mcp->mb[2] = MSW(LSD(pdb_dma));
mcp->mb[3] = LSW(LSD(pdb_dma));
mcp->mb[6] = MSW(MSD(pdb_dma));
mcp->mb[7] = LSW(MSD(pdb_dma));
mcp->mb[9] = 0;
mcp->mb[10] = 0;
mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_1|MBX_0;
mcp->buf_size = sizeof(*pdb);
mcp->flags = MBX_DMA_IN;
mcp->tov = vha->hw->login_timeout * 2;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x111a,
"Failed=%x mb[0]=%x mb[1]=%x.\n",
rval, mcp->mb[0], mcp->mb[1]);
} else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111b,
"Done %s.\n", __func__);
}
dma_unmap_single(&vha->hw->pdev->dev, pdb_dma,
sizeof(*pdb), DMA_FROM_DEVICE);
return rval;
}
/*
* qla2x00_get_firmware_state
* Get adapter firmware state.
@@ -2384,7 +2421,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
lg->entry_count = 1;
lg->handle = MAKE_HANDLE(req->id, lg->handle);
lg->handle = make_handle(req->id, lg->handle);
lg->nport_handle = cpu_to_le16(loop_id);
lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
if (opt & BIT_0)
@@ -2654,7 +2691,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
req = vha->req;
lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
lg->entry_count = 1;
lg->handle = MAKE_HANDLE(req->id, lg->handle);
lg->handle = make_handle(req->id, lg->handle);
lg->nport_handle = cpu_to_le16(loop_id);
lg->control_flags =
cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
@@ -3060,18 +3097,19 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
int rval;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
uint32_t *iter, dwords;
uint32_t *iter = (void *)stats;
ushort dwords = sizeof(*stats)/sizeof(*iter);
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
"Entered %s.\n", __func__);
memset(&mc, 0, sizeof(mc));
mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
mc.mb[2] = MSW(stats_dma);
mc.mb[3] = LSW(stats_dma);
mc.mb[2] = MSW(LSD(stats_dma));
mc.mb[3] = LSW(LSD(stats_dma));
mc.mb[6] = MSW(MSD(stats_dma));
mc.mb[7] = LSW(MSD(stats_dma));
mc.mb[8] = sizeof(struct link_statistics) / 4;
mc.mb[8] = dwords;
mc.mb[9] = cpu_to_le16(vha->vp_idx);
mc.mb[10] = cpu_to_le16(options);
@@ -3086,8 +3124,6 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
"Done %s.\n", __func__);
/* Re-endianize - firmware data is le32. */
dwords = sizeof(struct link_statistics) / 4;
iter = &stats->link_fail_cnt;
for ( ; dwords--; iter++)
le32_to_cpus(iter);
}
@@ -3145,9 +3181,9 @@ qla24xx_abort_command(srb_t *sp)
abt->entry_type = ABORT_IOCB_TYPE;
abt->entry_count = 1;
abt->handle = MAKE_HANDLE(req->id, abt->handle);
abt->handle = make_handle(req->id, abt->handle);
abt->nport_handle = cpu_to_le16(fcport->loop_id);
abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
abt->handle_to_abort = make_handle(req->id, handle);
abt->port_id[0] = fcport->d_id.b.al_pa;
abt->port_id[1] = fcport->d_id.b.area;
abt->port_id[2] = fcport->d_id.b.domain;
@@ -3224,7 +3260,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
tsk->p.tsk.entry_count = 1;
tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
tsk->p.tsk.handle = make_handle(req->id, tsk->p.tsk.handle);
tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
tsk->p.tsk.control_flags = cpu_to_le32(type);
@@ -3888,11 +3924,29 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
fcport->scan_state = QLA_FCPORT_SCAN;
fcport->n2n_flag = 0;
}
id.b24 = 0;
if (wwn_to_u64(vha->port_name) >
wwn_to_u64(rptid_entry->u.f1.port_name)) {
vha->d_id.b24 = 0;
vha->d_id.b.al_pa = 1;
ha->flags.n2n_bigger = 1;
id.b.al_pa = 2;
ql_dbg(ql_dbg_async, vha, 0x5075,
"Format 1: assign local id %x remote id %x\n",
vha->d_id.b24, id.b24);
} else {
ql_dbg(ql_dbg_async, vha, 0x5075,
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
rptid_entry->u.f1.port_name);
ha->flags.n2n_bigger = 0;
}
fcport = qla2x00_find_fcport_by_wwpn(vha,
rptid_entry->u.f1.port_name, 1);
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
if (fcport) {
fcport->plogi_nack_done_deadline = jiffies + HZ;
fcport->dm_login_expire = jiffies + 2*HZ;
@@ -3903,6 +3957,11 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
if (vha->flags.nvme_enabled)
fcport->fc4_type |= FS_FC4TYPE_NVME;
if (wwn_to_u64(vha->port_name) >
wwn_to_u64(fcport->port_name)) {
fcport->d_id = id;
}
switch (fcport->disc_state) {
case DSC_DELETED:
set_bit(RELOGIN_NEEDED,
@@ -3915,25 +3974,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
break;
}
} else {
id.b24 = 0;
if (wwn_to_u64(vha->port_name) >
wwn_to_u64(rptid_entry->u.f1.port_name)) {
vha->d_id.b24 = 0;
vha->d_id.b.al_pa = 1;
ha->flags.n2n_bigger = 1;
ha->flags.n2n_ae = 0;
id.b.al_pa = 2;
ql_dbg(ql_dbg_async, vha, 0x5075,
"Format 1: assign local id %x remote id %x\n",
vha->d_id.b24, id.b24);
} else {
ql_dbg(ql_dbg_async, vha, 0x5075,
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
rptid_entry->u.f1.port_name);
ha->flags.n2n_bigger = 0;
ha->flags.n2n_ae = 1;
}
qla24xx_post_newsess_work(vha, &id,
rptid_entry->u.f1.port_name,
rptid_entry->u.f1.node_name,
@@ -4827,6 +4867,103 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
return rval;
}
int
qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
{
int rval;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
uint8_t *els_cmd_map;
dma_addr_t els_cmd_map_dma;
uint cmd_opcode = ELS_COMMAND_RDP;
uint index = cmd_opcode / 8;
uint bit = cmd_opcode % 8;
struct qla_hw_data *ha = vha->hw;
if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha))
return QLA_SUCCESS;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
"Entered %s.\n", __func__);
els_cmd_map = dma_alloc_coherent(&ha->pdev->dev, ELS_CMD_MAP_SIZE,
&els_cmd_map_dma, GFP_KERNEL);
if (!els_cmd_map) {
ql_log(ql_log_warn, vha, 0x7101,
"Failed to allocate RDP els command param.\n");
return QLA_MEMORY_ALLOC_FAILED;
}
memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
els_cmd_map[index] |= 1 << bit;
mcp->mb[0] = MBC_SET_RNID_PARAMS;
mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
mcp->mb[2] = MSW(LSD(els_cmd_map_dma));
mcp->mb[3] = LSW(LSD(els_cmd_map_dma));
mcp->mb[6] = MSW(MSD(els_cmd_map_dma));
mcp->mb[7] = LSW(MSD(els_cmd_map_dma));
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_1|MBX_0;
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = MBX_DMA_OUT;
mcp->buf_size = ELS_CMD_MAP_SIZE;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x118d,
"Failed=%x (%x,%x).\n", rval, mcp->mb[0], mcp->mb[1]);
} else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
"Done %s.\n", __func__);
}
dma_free_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
els_cmd_map, els_cmd_map_dma);
return rval;
}
int
qla24xx_get_buffer_credits(scsi_qla_host_t *vha, struct buffer_credit_24xx *bbc,
dma_addr_t bbc_dma)
{
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
int rval;
if (!IS_FWI2_CAPABLE(vha->hw))
return QLA_FUNCTION_FAILED;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118e,
"Entered %s.\n", __func__);
mcp->mb[0] = MBC_GET_RNID_PARAMS;
mcp->mb[1] = RNID_BUFFER_CREDITS << 8;
mcp->mb[2] = MSW(LSD(bbc_dma));
mcp->mb[3] = LSW(LSD(bbc_dma));
mcp->mb[6] = MSW(MSD(bbc_dma));
mcp->mb[7] = LSW(MSD(bbc_dma));
mcp->mb[8] = sizeof(*bbc) / sizeof(*bbc->parameter);
mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_1|MBX_0;
mcp->buf_size = sizeof(*bbc);
mcp->flags = MBX_DMA_IN;
mcp->tov = MBX_TOV_SECONDS;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x118f,
"Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
} else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1190,
"Done %s.\n", __func__);
}
return rval;
}
static int
qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
{
@@ -4880,8 +5017,8 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
mcp->mb[0] = MBC_READ_SFP;
mcp->mb[1] = dev;
mcp->mb[2] = MSW(sfp_dma);
mcp->mb[3] = LSW(sfp_dma);
mcp->mb[2] = MSW(LSD(sfp_dma));
mcp->mb[3] = LSW(LSD(sfp_dma));
mcp->mb[6] = MSW(MSD(sfp_dma));
mcp->mb[7] = LSW(MSD(sfp_dma));
mcp->mb[8] = len;
@@ -4934,8 +5071,8 @@ qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
mcp->mb[0] = MBC_WRITE_SFP;
mcp->mb[1] = dev;
mcp->mb[2] = MSW(sfp_dma);
mcp->mb[3] = LSW(sfp_dma);
mcp->mb[2] = MSW(LSD(sfp_dma));
mcp->mb[3] = LSW(LSD(sfp_dma));
mcp->mb[6] = MSW(MSD(sfp_dma));
mcp->mb[7] = LSW(MSD(sfp_dma));
mcp->mb[8] = len;
@@ -5170,10 +5307,11 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
mcp->out_mb |= MBX_2;
mcp->in_mb = MBX_0;
if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
if (IS_CNA_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
mcp->in_mb |= MBX_1;
if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||
IS_QLA28XX(ha))
mcp->in_mb |= MBX_3;
mcp->tov = MBX_TOV_SECONDS;
@@ -5407,6 +5545,15 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_mbx, vha, 0x1107,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
} else {
if (mcp->mb[1] != 0x7)
ha->link_data_rate = mcp->mb[1];
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
if (mcp->mb[4] & BIT_0)
ql_log(ql_log_info, vha, 0x11a2,
"FEC=enabled (data rate).\n");
}
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
"Done %s.\n", __func__);
if (mcp->mb[1] != 0x7)
@@ -6688,3 +6835,60 @@ int qla2xxx_read_remote_register(scsi_qla_host_t *vha, uint32_t addr,
return rval;
}
int
ql26xx_led_config(scsi_qla_host_t *vha, uint16_t options, uint16_t *led)
{
struct qla_hw_data *ha = vha->hw;
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
int rval;
if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return QLA_FUNCTION_FAILED;
ql_dbg(ql_dbg_mbx, vha, 0x7070, "Entered %s (options=%x).\n",
__func__, options);
mcp->mb[0] = MBC_SET_GET_FC_LED_CONFIG;
mcp->mb[1] = options;
mcp->out_mb = MBX_1|MBX_0;
mcp->in_mb = MBX_1|MBX_0;
if (options & BIT_0) {
if (options & BIT_1) {
mcp->mb[2] = led[2];
mcp->out_mb |= MBX_2;
}
if (options & BIT_2) {
mcp->mb[3] = led[0];
mcp->out_mb |= MBX_3;
}
if (options & BIT_3) {
mcp->mb[4] = led[1];
mcp->out_mb |= MBX_4;
}
} else {
mcp->in_mb |= MBX_4|MBX_3|MBX_2;
}
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval) {
ql_dbg(ql_dbg_mbx, vha, 0x7071, "Failed %s %x (mb=%x,%x)\n",
__func__, rval, mcp->mb[0], mcp->mb[1]);
return rval;
}
if (options & BIT_0) {
ha->beacon_blink_led = 0;
ql_dbg(ql_dbg_mbx, vha, 0x7072, "Done %s\n", __func__);
} else {
led[2] = mcp->mb[2];
led[0] = mcp->mb[3];
led[1] = mcp->mb[4];
ql_dbg(ql_dbg_mbx, vha, 0x7073, "Done %s (led=%x,%x,%x)\n",
__func__, led[0], led[1], led[2]);
}
return rval;
}
+12 -1
View File
@@ -361,6 +361,13 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
}
}
if (test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags)) {
if (atomic_read(&vha->loop_state) == LOOP_READY) {
qla24xx_process_purex_list(&vha->purex_list);
clear_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
}
}
if (test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) {
ql_dbg(ql_dbg_dpc, vha, 0x4016,
"FCPort update scheduled.\n");
@@ -509,6 +516,9 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
vha->mgmt_svr_loop_id = qla2x00_reserve_mgmt_server_loop_id(vha);
vha->dpc_flags = 0L;
ha->dpc_active = 0;
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
/*
* To fix the issue of processing a parent's RSCN for the vport before
@@ -886,7 +896,8 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
rsp->rsp_q_out);
ret = qla25xx_request_irq(ha, qpair, qpair->msix,
QLA_MSIX_QPAIR_MULTIQ_RSP_Q);
ha->flags.disable_msix_handshake ?
QLA_MSIX_QPAIR_MULTIQ_RSP_Q : QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS);
if (ret)
goto que_failed;
+6 -7
View File
@@ -53,10 +53,9 @@ qlafx00_mailbox_command(scsi_qla_host_t *vha, struct mbx_cmd_32 *mcp)
struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
if (ha->pdev->error_state > pci_channel_io_frozen) {
if (ha->pdev->error_state == pci_channel_io_perm_failure) {
ql_log(ql_log_warn, vha, 0x115c,
"error_state is greater than pci_channel_io_frozen, "
"exiting.\n");
"PCI channel failed permanently, exiting.\n");
return QLA_FUNCTION_TIMEOUT;
}
@@ -3149,7 +3148,7 @@ qlafx00_start_scsi(srb_t *sp)
memset(&lcmd_pkt, 0, REQUEST_ENTRY_SIZE);
lcmd_pkt.handle = MAKE_HANDLE(req->id, sp->handle);
lcmd_pkt.handle = make_handle(req->id, sp->handle);
lcmd_pkt.reserved_0 = 0;
lcmd_pkt.port_path_ctrl = 0;
lcmd_pkt.reserved_1 = 0;
@@ -3219,7 +3218,7 @@ qlafx00_tm_iocb(srb_t *sp, struct tsk_mgmt_entry_fx00 *ptm_iocb)
memset(&tm_iocb, 0, sizeof(struct tsk_mgmt_entry_fx00));
tm_iocb.entry_type = TSK_MGMT_IOCB_TYPE_FX00;
tm_iocb.entry_count = 1;
tm_iocb.handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
tm_iocb.handle = cpu_to_le32(make_handle(req->id, sp->handle));
tm_iocb.reserved_0 = 0;
tm_iocb.tgt_id = cpu_to_le16(sp->fcport->tgt_id);
tm_iocb.control_flags = cpu_to_le32(fxio->u.tmf.flags);
@@ -3245,9 +3244,9 @@ qlafx00_abort_iocb(srb_t *sp, struct abort_iocb_entry_fx00 *pabt_iocb)
memset(&abt_iocb, 0, sizeof(struct abort_iocb_entry_fx00));
abt_iocb.entry_type = ABORT_IOCB_TYPE_FX00;
abt_iocb.entry_count = 1;
abt_iocb.handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
abt_iocb.handle = cpu_to_le32(make_handle(req->id, sp->handle));
abt_iocb.abort_handle =
cpu_to_le32(MAKE_HANDLE(req->id, fxio->u.abt.cmd_hndl));
cpu_to_le32(make_handle(req->id, fxio->u.abt.cmd_hndl));
abt_iocb.tgt_id_sts = cpu_to_le16(sp->fcport->tgt_id);
abt_iocb.req_que_no = cpu_to_le16(req->id);
+1 -1
View File
@@ -424,7 +424,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
req->cnt -= req_cnt;
cmd_pkt = (struct cmd_nvme *)req->ring_ptr;
cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
cmd_pkt->handle = make_handle(req->id, handle);
/* Zero out remaining portion of packet. */
clr_ptr = (uint32_t *)cmd_pkt + 2;
+659 -40
View File
@@ -126,7 +126,8 @@ module_param(ql2xfdmienable, int, S_IRUGO|S_IWUSR);
module_param_named(fdmi, ql2xfdmienable, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xfdmienable,
"Enables FDMI registrations. "
"0 - no FDMI. Default is 1 - perform FDMI.");
"0 - no FDMI registrations. "
"1 - provide FDMI registrations (default).");
#define MAX_Q_DEPTH 64
static int ql2xmaxqdepth = MAX_Q_DEPTH;
@@ -135,11 +136,7 @@ MODULE_PARM_DESC(ql2xmaxqdepth,
"Maximum queue depth to set for each LUN. "
"Default is 64.");
#if (IS_ENABLED(CONFIG_NVME_FC))
int ql2xenabledif;
#else
int ql2xenabledif = 2;
#endif
module_param(ql2xenabledif, int, S_IRUGO);
MODULE_PARM_DESC(ql2xenabledif,
" Enable T10-CRC-DIF:\n"
@@ -324,6 +321,22 @@ MODULE_PARM_DESC(ql2xdifbundlinginternalbuffers,
"0 (Default). Based on check.\n"
"1 Force using internal buffers\n");
int ql2xsmartsan;
module_param(ql2xsmartsan, int, 0444);
module_param_named(smartsan, ql2xsmartsan, int, 0444);
MODULE_PARM_DESC(ql2xsmartsan,
"Send SmartSAN Management Attributes for FDMI Registration."
" Default is 0 - No SmartSAN registration,"
" 1 - Register SmartSAN Management Attributes.");
int ql2xrdpenable;
module_param(ql2xrdpenable, int, 0444);
module_param_named(rdpenable, ql2xrdpenable, int, 0444);
MODULE_PARM_DESC(ql2xrdpenable,
"Enables RDP responses. "
"0 - no RDP responses (default). "
"1 - provide RDP responses.");
static void qla2x00_clear_drv_active(struct qla_hw_data *);
static void qla2x00_free_device(scsi_qla_host_t *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
@@ -603,6 +616,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len)
case 3:
speed_str = "8.0GT/s";
break;
case 4:
speed_str = "16.0GT/s";
break;
default:
speed_str = "<unknown>";
break;
@@ -1290,17 +1306,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
return SUCCESS;
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
if (sp->completed) {
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return SUCCESS;
}
if (sp->abort || sp->aborted) {
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return FAILED;
}
sp->abort = 1;
sp->comp = &comp;
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
@@ -1725,6 +1730,10 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
return QLA_SUCCESS;
}
/*
* The caller must ensure that no completion interrupts will happen
* while this function is in progress.
*/
static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
unsigned long *flags)
__releases(qp->qp_lock_ptr)
@@ -1733,10 +1742,13 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
DECLARE_COMPLETION_ONSTACK(comp);
scsi_qla_host_t *vha = qp->vha;
struct qla_hw_data *ha = vha->hw;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
int rval;
bool ret_cmd;
uint32_t ratov_j;
lockdep_assert_held(qp->qp_lock_ptr);
if (qla2x00_chip_is_down(vha)) {
sp->done(sp, res);
return;
@@ -1752,7 +1764,6 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
}
sp->comp = &comp;
sp->abort = 1;
spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
rval = ha->isp_ops->abort_command(sp);
@@ -1776,13 +1787,17 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
}
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
if (ret_cmd && (!sp->completed || !sp->aborted))
if (ret_cmd && blk_mq_request_started(cmd->request))
sp->done(sp, res);
} else {
sp->done(sp, res);
}
}
/*
* The caller must ensure that no completion interrupts will happen
* while this function is in progress.
*/
static void
__qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
{
@@ -1829,6 +1844,10 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
}
/*
* The caller must ensure that no completion interrupts will happen
* while this function is in progress.
*/
void
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
{
@@ -2326,7 +2345,7 @@ static struct isp_operations qla81xx_isp_ops = {
.config_rings = qla24xx_config_rings,
.reset_adapter = qla24xx_reset_adapter,
.nvram_config = qla81xx_nvram_config,
.update_fw_options = qla81xx_update_fw_options,
.update_fw_options = qla24xx_update_fw_options,
.load_risc = qla81xx_load_risc,
.pci_info_str = qla24xx_pci_info_str,
.fw_version_str = qla24xx_fw_version_str,
@@ -2443,7 +2462,7 @@ static struct isp_operations qla83xx_isp_ops = {
.config_rings = qla24xx_config_rings,
.reset_adapter = qla24xx_reset_adapter,
.nvram_config = qla81xx_nvram_config,
.update_fw_options = qla81xx_update_fw_options,
.update_fw_options = qla24xx_update_fw_options,
.load_risc = qla81xx_load_risc,
.pci_info_str = qla24xx_pci_info_str,
.fw_version_str = qla24xx_fw_version_str,
@@ -3482,13 +3501,6 @@ skip_dpc:
if (test_bit(UNLOADING, &base_vha->dpc_flags))
return -ENODEV;
if (ha->flags.detected_lr_sfp) {
ql_log(ql_log_info, base_vha, 0xffff,
"Reset chip to pick up LR SFP setting\n");
set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
qla2xxx_wake_dpc(base_vha);
}
return 0;
probe_failed:
@@ -3849,6 +3861,20 @@ qla2x00_remove_one(struct pci_dev *pdev)
pci_disable_device(pdev);
}
static inline void
qla24xx_free_purex_list(struct purex_list *list)
{
struct list_head *item, *next;
ulong flags;
spin_lock_irqsave(&list->lock, flags);
list_for_each_safe(item, next, &list->head) {
list_del(item);
kfree(list_entry(item, struct purex_item, list));
}
spin_unlock_irqrestore(&list->lock, flags);
}
static void
qla2x00_free_device(scsi_qla_host_t *vha)
{
@@ -3881,6 +3907,8 @@ qla2x00_free_device(scsi_qla_host_t *vha)
}
qla24xx_free_purex_list(&vha->purex_list);
qla2x00_mem_free(ha);
qla82xx_md_free(vha);
@@ -4854,6 +4882,9 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
INIT_LIST_HEAD(&vha->gpnid_list);
INIT_WORK(&vha->iocb_work, qla2x00_iocb_work_fn);
INIT_LIST_HEAD(&vha->purex_list.head);
spin_lock_init(&vha->purex_list.lock);
spin_lock_init(&vha->work_lock);
spin_lock_init(&vha->cmd_list_lock);
init_waitqueue_head(&vha->fcport_waitQ);
@@ -5215,9 +5246,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
fcport->n2n_flag = 1;
}
fcport->fw_login_state = 0;
/*
* wait link init done before sending login
*/
schedule_delayed_work(&vha->scan.scan_work, 5);
} else {
qla24xx_fcport_handle_login(vha, fcport);
}
@@ -5778,6 +5808,583 @@ retry_lock:
return;
}
static bool
qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha,
struct purex_entry_24xx *purex)
{
char fwstr[16];
u32 sid = purex->s_id[2] << 16 | purex->s_id[1] << 8 | purex->s_id[0];
struct port_database_24xx *pdb;
/* Domain Controller is always logged-out. */
/* if RDP request is not from Domain Controller: */
if (sid != 0xfffc01)
return false;
ql_dbg(ql_dbg_init, vha, 0x0181, "%s: s_id=%#x\n", __func__, sid);
pdb = kzalloc(sizeof(*pdb), GFP_KERNEL);
if (!pdb) {
ql_dbg(ql_dbg_init, vha, 0x0181,
"%s: Failed allocate pdb\n", __func__);
} else if (qla24xx_get_port_database(vha, purex->nport_handle, pdb)) {
ql_dbg(ql_dbg_init, vha, 0x0181,
"%s: Failed get pdb sid=%x\n", __func__, sid);
} else if (pdb->current_login_state != PDS_PLOGI_COMPLETE &&
pdb->current_login_state != PDS_PRLI_COMPLETE) {
ql_dbg(ql_dbg_init, vha, 0x0181,
"%s: Port not logged in sid=%#x\n", __func__, sid);
} else {
/* RDP request is from logged in port */
kfree(pdb);
return false;
}
kfree(pdb);
vha->hw->isp_ops->fw_version_str(vha, fwstr, sizeof(fwstr));
fwstr[strcspn(fwstr, " ")] = 0;
/* if FW version allows RDP response length upto 2048 bytes: */
if (strcmp(fwstr, "8.09.00") > 0 || strcmp(fwstr, "8.05.65") == 0)
return false;
ql_dbg(ql_dbg_init, vha, 0x0181, "%s: fw=%s\n", __func__, fwstr);
/* RDP response length is to be reduced to maximum 256 bytes */
return true;
}
static uint
qla25xx_rdp_port_speed_capability(struct qla_hw_data *ha)
{
if (IS_CNA_CAPABLE(ha))
return RDP_PORT_SPEED_10GB;
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
unsigned int speeds = 0;
if (ha->max_supported_speed == 2) {
if (ha->min_supported_speed <= 6)
speeds |= RDP_PORT_SPEED_64GB;
}
if (ha->max_supported_speed == 2 ||
ha->max_supported_speed == 1) {
if (ha->min_supported_speed <= 5)
speeds |= RDP_PORT_SPEED_32GB;
}
if (ha->max_supported_speed == 2 ||
ha->max_supported_speed == 1 ||
ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 4)
speeds |= RDP_PORT_SPEED_16GB;
}
if (ha->max_supported_speed == 1 ||
ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 3)
speeds |= RDP_PORT_SPEED_8GB;
}
if (ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 2)
speeds |= RDP_PORT_SPEED_4GB;
}
return speeds;
}
if (IS_QLA2031(ha))
return RDP_PORT_SPEED_16GB|RDP_PORT_SPEED_8GB|
RDP_PORT_SPEED_4GB;
if (IS_QLA25XX(ha))
return RDP_PORT_SPEED_8GB|RDP_PORT_SPEED_4GB|
RDP_PORT_SPEED_2GB|RDP_PORT_SPEED_1GB;
if (IS_QLA24XX_TYPE(ha))
return RDP_PORT_SPEED_4GB|RDP_PORT_SPEED_2GB|
RDP_PORT_SPEED_1GB;
if (IS_QLA23XX(ha))
return RDP_PORT_SPEED_2GB|RDP_PORT_SPEED_1GB;
return RDP_PORT_SPEED_1GB;
}
static uint
qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
{
switch (ha->link_data_rate) {
case PORT_SPEED_1GB:
return RDP_PORT_SPEED_1GB;
case PORT_SPEED_2GB:
return RDP_PORT_SPEED_2GB;
case PORT_SPEED_4GB:
return RDP_PORT_SPEED_4GB;
case PORT_SPEED_8GB:
return RDP_PORT_SPEED_8GB;
case PORT_SPEED_10GB:
return RDP_PORT_SPEED_10GB;
case PORT_SPEED_16GB:
return RDP_PORT_SPEED_16GB;
case PORT_SPEED_32GB:
return RDP_PORT_SPEED_32GB;
case PORT_SPEED_64GB:
return RDP_PORT_SPEED_64GB;
default:
return RDP_PORT_SPEED_UNKNOWN;
}
}
/*
* Function Name: qla24xx_process_purex_iocb
*
* Description:
* Prepare a RDP response and send to Fabric switch
*
* PARAMETERS:
* vha: SCSI qla host
* purex: RDP request received by HBA
*/
void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
{
struct qla_hw_data *ha = vha->hw;
struct purex_entry_24xx *purex = pkt;
dma_addr_t rsp_els_dma;
dma_addr_t rsp_payload_dma;
dma_addr_t stat_dma;
dma_addr_t bbc_dma;
dma_addr_t sfp_dma;
struct els_entry_24xx *rsp_els = NULL;
struct rdp_rsp_payload *rsp_payload = NULL;
struct link_statistics *stat = NULL;
struct buffer_credit_24xx *bbc = NULL;
uint8_t *sfp = NULL;
uint16_t sfp_flags = 0;
uint rsp_payload_length = sizeof(*rsp_payload);
int rval;
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0180,
"%s: Enter\n", __func__);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0181,
"-------- ELS REQ -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0182,
(void *)purex, sizeof(*purex));
if (qla25xx_rdp_rsp_reduce_size(vha, purex)) {
rsp_payload_length =
offsetof(typeof(*rsp_payload), optical_elmt_desc);
ql_dbg(ql_dbg_init, vha, 0x0181,
"Reducing RSP payload length to %u bytes...\n",
rsp_payload_length);
}
rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els),
&rsp_els_dma, GFP_KERNEL);
if (!rsp_els) {
ql_log(ql_log_warn, vha, 0x0183,
"Failed allocate dma buffer ELS RSP.\n");
goto dealloc;
}
rsp_payload = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_payload),
&rsp_payload_dma, GFP_KERNEL);
if (!rsp_payload) {
ql_log(ql_log_warn, vha, 0x0184,
"Failed allocate dma buffer ELS RSP payload.\n");
goto dealloc;
}
sfp = dma_alloc_coherent(&ha->pdev->dev, SFP_RTDI_LEN,
&sfp_dma, GFP_KERNEL);
stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat),
&stat_dma, GFP_KERNEL);
bbc = dma_alloc_coherent(&ha->pdev->dev, sizeof(*bbc),
&bbc_dma, GFP_KERNEL);
/* Prepare Response IOCB */
rsp_els->entry_type = ELS_IOCB_TYPE;
rsp_els->entry_count = 1;
rsp_els->sys_define = 0;
rsp_els->entry_status = 0;
rsp_els->handle = 0;
rsp_els->nport_handle = purex->nport_handle;
rsp_els->tx_dsd_count = 1;
rsp_els->vp_index = purex->vp_idx;
rsp_els->sof_type = EST_SOFI3;
rsp_els->rx_xchg_address = purex->rx_xchg_addr;
rsp_els->rx_dsd_count = 0;
rsp_els->opcode = purex->els_frame_payload[0];
rsp_els->d_id[0] = purex->s_id[0];
rsp_els->d_id[1] = purex->s_id[1];
rsp_els->d_id[2] = purex->s_id[2];
rsp_els->control_flags = EPD_ELS_ACC;
rsp_els->rx_byte_count = 0;
rsp_els->tx_byte_count = cpu_to_le32(rsp_payload_length);
put_unaligned_le64(rsp_payload_dma, &rsp_els->tx_address);
rsp_els->tx_len = rsp_els->tx_byte_count;
rsp_els->rx_address = 0;
rsp_els->rx_len = 0;
/* Prepare Response Payload */
rsp_payload->hdr.cmd = cpu_to_be32(0x2 << 24); /* LS_ACC */
rsp_payload->hdr.len = cpu_to_be32(
rsp_els->tx_byte_count - sizeof(rsp_payload->hdr));
/* Link service Request Info Descriptor */
rsp_payload->ls_req_info_desc.desc_tag = cpu_to_be32(0x1);
rsp_payload->ls_req_info_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_req_info_desc));
rsp_payload->ls_req_info_desc.req_payload_word_0 =
cpu_to_be32p((uint32_t *)purex->els_frame_payload);
/* Link service Request Info Descriptor 2 */
rsp_payload->ls_req_info_desc2.desc_tag = cpu_to_be32(0x1);
rsp_payload->ls_req_info_desc2.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_req_info_desc2));
rsp_payload->ls_req_info_desc2.req_payload_word_0 =
cpu_to_be32p((uint32_t *)purex->els_frame_payload);
rsp_payload->sfp_diag_desc.desc_tag = cpu_to_be32(0x10000);
rsp_payload->sfp_diag_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->sfp_diag_desc));
if (sfp) {
/* SFP Flags */
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 0x7, 2, 0);
if (!rval) {
/* SFP Flags bits 3-0: Port Tx Laser Type */
if (sfp[0] & BIT_2 || sfp[1] & (BIT_6|BIT_5))
sfp_flags |= BIT_0; /* short wave */
else if (sfp[0] & BIT_1)
sfp_flags |= BIT_1; /* long wave 1310nm */
else if (sfp[1] & BIT_4)
sfp_flags |= BIT_1|BIT_0; /* long wave 1550nm */
}
/* SFP Type */
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 0x0, 1, 0);
if (!rval) {
sfp_flags |= BIT_4; /* optical */
if (sfp[0] == 0x3)
sfp_flags |= BIT_6; /* sfp+ */
}
rsp_payload->sfp_diag_desc.sfp_flags = cpu_to_be16(sfp_flags);
/* SFP Diagnostics */
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0x60, 10, 0);
if (!rval) {
uint16_t *trx = (void *)sfp; /* already be16 */
rsp_payload->sfp_diag_desc.temperature = trx[0];
rsp_payload->sfp_diag_desc.vcc = trx[1];
rsp_payload->sfp_diag_desc.tx_bias = trx[2];
rsp_payload->sfp_diag_desc.tx_power = trx[3];
rsp_payload->sfp_diag_desc.rx_power = trx[4];
}
}
/* Port Speed Descriptor */
rsp_payload->port_speed_desc.desc_tag = cpu_to_be32(0x10001);
rsp_payload->port_speed_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_speed_desc));
rsp_payload->port_speed_desc.speed_capab = cpu_to_be16(
qla25xx_rdp_port_speed_capability(ha));
rsp_payload->port_speed_desc.operating_speed = cpu_to_be16(
qla25xx_rdp_port_speed_currently(ha));
/* Link Error Status Descriptor */
rsp_payload->ls_err_desc.desc_tag = cpu_to_be32(0x10002);
rsp_payload->ls_err_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->ls_err_desc));
if (stat) {
rval = qla24xx_get_isp_stats(vha, stat, stat_dma, 0);
if (!rval) {
rsp_payload->ls_err_desc.link_fail_cnt =
cpu_to_be32(stat->link_fail_cnt);
rsp_payload->ls_err_desc.loss_sync_cnt =
cpu_to_be32(stat->loss_sync_cnt);
rsp_payload->ls_err_desc.loss_sig_cnt =
cpu_to_be32(stat->loss_sig_cnt);
rsp_payload->ls_err_desc.prim_seq_err_cnt =
cpu_to_be32(stat->prim_seq_err_cnt);
rsp_payload->ls_err_desc.inval_xmit_word_cnt =
cpu_to_be32(stat->inval_xmit_word_cnt);
rsp_payload->ls_err_desc.inval_crc_cnt =
cpu_to_be32(stat->inval_crc_cnt);
rsp_payload->ls_err_desc.pn_port_phy_type |= BIT_6;
}
}
/* Portname Descriptor */
rsp_payload->port_name_diag_desc.desc_tag = cpu_to_be32(0x10003);
rsp_payload->port_name_diag_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_name_diag_desc));
memcpy(rsp_payload->port_name_diag_desc.WWNN,
vha->node_name,
sizeof(rsp_payload->port_name_diag_desc.WWNN));
memcpy(rsp_payload->port_name_diag_desc.WWPN,
vha->port_name,
sizeof(rsp_payload->port_name_diag_desc.WWPN));
/* F-Port Portname Descriptor */
rsp_payload->port_name_direct_desc.desc_tag = cpu_to_be32(0x10003);
rsp_payload->port_name_direct_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_name_direct_desc));
memcpy(rsp_payload->port_name_direct_desc.WWNN,
vha->fabric_node_name,
sizeof(rsp_payload->port_name_direct_desc.WWNN));
memcpy(rsp_payload->port_name_direct_desc.WWPN,
vha->fabric_port_name,
sizeof(rsp_payload->port_name_direct_desc.WWPN));
/* Bufer Credit Descriptor */
rsp_payload->buffer_credit_desc.desc_tag = cpu_to_be32(0x10006);
rsp_payload->buffer_credit_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->buffer_credit_desc));
rsp_payload->buffer_credit_desc.fcport_b2b = 0;
rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0);
rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0);
if (bbc) {
memset(bbc, 0, sizeof(*bbc));
rval = qla24xx_get_buffer_credits(vha, bbc, bbc_dma);
if (!rval) {
rsp_payload->buffer_credit_desc.fcport_b2b =
cpu_to_be32(LSW(bbc->parameter[0]));
}
}
if (rsp_payload_length < sizeof(*rsp_payload))
goto send;
/* Optical Element Descriptor, Temperature */
rsp_payload->optical_elmt_desc[0].desc_tag = cpu_to_be32(0x10007);
rsp_payload->optical_elmt_desc[0].desc_len =
cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc));
/* Optical Element Descriptor, Voltage */
rsp_payload->optical_elmt_desc[1].desc_tag = cpu_to_be32(0x10007);
rsp_payload->optical_elmt_desc[1].desc_len =
cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc));
/* Optical Element Descriptor, Tx Bias Current */
rsp_payload->optical_elmt_desc[2].desc_tag = cpu_to_be32(0x10007);
rsp_payload->optical_elmt_desc[2].desc_len =
cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc));
/* Optical Element Descriptor, Tx Power */
rsp_payload->optical_elmt_desc[3].desc_tag = cpu_to_be32(0x10007);
rsp_payload->optical_elmt_desc[3].desc_len =
cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc));
/* Optical Element Descriptor, Rx Power */
rsp_payload->optical_elmt_desc[4].desc_tag = cpu_to_be32(0x10007);
rsp_payload->optical_elmt_desc[4].desc_len =
cpu_to_be32(RDP_DESC_LEN(*rsp_payload->optical_elmt_desc));
if (sfp) {
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0, 64, 0);
if (!rval) {
uint16_t *trx = (void *)sfp; /* already be16 */
/* Optical Element Descriptor, Temperature */
rsp_payload->optical_elmt_desc[0].high_alarm = trx[0];
rsp_payload->optical_elmt_desc[0].low_alarm = trx[1];
rsp_payload->optical_elmt_desc[0].high_warn = trx[2];
rsp_payload->optical_elmt_desc[0].low_warn = trx[3];
rsp_payload->optical_elmt_desc[0].element_flags =
cpu_to_be32(1 << 28);
/* Optical Element Descriptor, Voltage */
rsp_payload->optical_elmt_desc[1].high_alarm = trx[4];
rsp_payload->optical_elmt_desc[1].low_alarm = trx[5];
rsp_payload->optical_elmt_desc[1].high_warn = trx[6];
rsp_payload->optical_elmt_desc[1].low_warn = trx[7];
rsp_payload->optical_elmt_desc[1].element_flags =
cpu_to_be32(2 << 28);
/* Optical Element Descriptor, Tx Bias Current */
rsp_payload->optical_elmt_desc[2].high_alarm = trx[8];
rsp_payload->optical_elmt_desc[2].low_alarm = trx[9];
rsp_payload->optical_elmt_desc[2].high_warn = trx[10];
rsp_payload->optical_elmt_desc[2].low_warn = trx[11];
rsp_payload->optical_elmt_desc[2].element_flags =
cpu_to_be32(3 << 28);
/* Optical Element Descriptor, Tx Power */
rsp_payload->optical_elmt_desc[3].high_alarm = trx[12];
rsp_payload->optical_elmt_desc[3].low_alarm = trx[13];
rsp_payload->optical_elmt_desc[3].high_warn = trx[14];
rsp_payload->optical_elmt_desc[3].low_warn = trx[15];
rsp_payload->optical_elmt_desc[3].element_flags =
cpu_to_be32(4 << 28);
/* Optical Element Descriptor, Rx Power */
rsp_payload->optical_elmt_desc[4].high_alarm = trx[16];
rsp_payload->optical_elmt_desc[4].low_alarm = trx[17];
rsp_payload->optical_elmt_desc[4].high_warn = trx[18];
rsp_payload->optical_elmt_desc[4].low_warn = trx[19];
rsp_payload->optical_elmt_desc[4].element_flags =
cpu_to_be32(5 << 28);
}
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 112, 64, 0);
if (!rval) {
/* Temperature high/low alarm/warning */
rsp_payload->optical_elmt_desc[0].element_flags |=
cpu_to_be32(
(sfp[0] >> 7 & 1) << 3 |
(sfp[0] >> 6 & 1) << 2 |
(sfp[4] >> 7 & 1) << 1 |
(sfp[4] >> 6 & 1) << 0);
/* Voltage high/low alarm/warning */
rsp_payload->optical_elmt_desc[1].element_flags |=
cpu_to_be32(
(sfp[0] >> 5 & 1) << 3 |
(sfp[0] >> 4 & 1) << 2 |
(sfp[4] >> 5 & 1) << 1 |
(sfp[4] >> 4 & 1) << 0);
/* Tx Bias Current high/low alarm/warning */
rsp_payload->optical_elmt_desc[2].element_flags |=
cpu_to_be32(
(sfp[0] >> 3 & 1) << 3 |
(sfp[0] >> 2 & 1) << 2 |
(sfp[4] >> 3 & 1) << 1 |
(sfp[4] >> 2 & 1) << 0);
/* Tx Power high/low alarm/warning */
rsp_payload->optical_elmt_desc[3].element_flags |=
cpu_to_be32(
(sfp[0] >> 1 & 1) << 3 |
(sfp[0] >> 0 & 1) << 2 |
(sfp[4] >> 1 & 1) << 1 |
(sfp[4] >> 0 & 1) << 0);
/* Rx Power high/low alarm/warning */
rsp_payload->optical_elmt_desc[4].element_flags |=
cpu_to_be32(
(sfp[1] >> 7 & 1) << 3 |
(sfp[1] >> 6 & 1) << 2 |
(sfp[5] >> 7 & 1) << 1 |
(sfp[5] >> 6 & 1) << 0);
}
}
/* Optical Product Data Descriptor */
rsp_payload->optical_prod_desc.desc_tag = cpu_to_be32(0x10008);
rsp_payload->optical_prod_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->optical_prod_desc));
if (sfp) {
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 20, 64, 0);
if (!rval) {
memcpy(rsp_payload->optical_prod_desc.vendor_name,
sfp + 0,
sizeof(rsp_payload->optical_prod_desc.vendor_name));
memcpy(rsp_payload->optical_prod_desc.part_number,
sfp + 20,
sizeof(rsp_payload->optical_prod_desc.part_number));
memcpy(rsp_payload->optical_prod_desc.revision,
sfp + 36,
sizeof(rsp_payload->optical_prod_desc.revision));
memcpy(rsp_payload->optical_prod_desc.serial_number,
sfp + 48,
sizeof(rsp_payload->optical_prod_desc.serial_number));
}
memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa0, 84, 8, 0);
if (!rval) {
memcpy(rsp_payload->optical_prod_desc.date,
sfp + 0,
sizeof(rsp_payload->optical_prod_desc.date));
}
}
send:
ql_dbg(ql_dbg_init, vha, 0x0183,
"Sending ELS Response to RDP Request...\n");
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0184,
"-------- ELS RSP -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0185,
(void *)rsp_els, sizeof(*rsp_els));
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0186,
"-------- ELS RSP PAYLOAD -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0187,
(void *)rsp_payload, rsp_payload_length);
rval = qla2x00_issue_iocb(vha, rsp_els, rsp_els_dma, 0);
if (rval) {
ql_log(ql_log_warn, vha, 0x0188,
"%s: iocb failed to execute -> %x\n", __func__, rval);
} else if (rsp_els->comp_status) {
ql_log(ql_log_warn, vha, 0x0189,
"%s: iocb failed to complete -> completion=%#x subcode=(%#x,%#x)\n",
__func__, rsp_els->comp_status,
rsp_els->error_subcode_1, rsp_els->error_subcode_2);
} else {
ql_dbg(ql_dbg_init, vha, 0x018a, "%s: done.\n", __func__);
}
dealloc:
if (bbc)
dma_free_coherent(&ha->pdev->dev, sizeof(*bbc),
bbc, bbc_dma);
if (stat)
dma_free_coherent(&ha->pdev->dev, sizeof(*stat),
stat, stat_dma);
if (sfp)
dma_free_coherent(&ha->pdev->dev, SFP_RTDI_LEN,
sfp, sfp_dma);
if (rsp_payload)
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_payload),
rsp_payload, rsp_payload_dma);
if (rsp_els)
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els),
rsp_els, rsp_els_dma);
}
void qla24xx_process_purex_list(struct purex_list *list)
{
struct list_head head = LIST_HEAD_INIT(head);
struct purex_item *item, *next;
ulong flags;
spin_lock_irqsave(&list->lock, flags);
list_splice_init(&list->head, &head);
spin_unlock_irqrestore(&list->lock, flags);
list_for_each_entry_safe(item, next, &head, list) {
list_del(&item->list);
item->process_item(item->vha, &item->iocb);
kfree(item);
}
}
void
qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{
@@ -6301,13 +6908,14 @@ qla2x00_do_dpc(void *data)
}
if (test_and_clear_bit(DETECT_SFP_CHANGE,
&base_vha->dpc_flags) &&
!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) {
qla24xx_detect_sfp(base_vha);
if (ha->flags.detected_lr_sfp !=
ha->flags.using_lr_setting)
set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
&base_vha->dpc_flags)) {
/* Semantic:
* - NO-OP -- await next ISP-ABORT. Preferred method
* to minimize disruptions that will occur
* when a forced chip-reset occurs.
* - Force -- ISP-ABORT scheduled.
*/
/* set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); */
}
if (test_and_clear_bit
@@ -6348,6 +6956,15 @@ qla2x00_do_dpc(void *data)
}
}
if (test_bit(PROCESS_PUREX_IOCB, &base_vha->dpc_flags)) {
if (atomic_read(&base_vha->loop_state) == LOOP_READY) {
qla24xx_process_purex_list
(&base_vha->purex_list);
clear_bit(PROCESS_PUREX_IOCB,
&base_vha->dpc_flags);
}
}
if (test_and_clear_bit(FCPORT_UPDATE_NEEDED,
&base_vha->dpc_flags)) {
qla2x00_update_fcports(base_vha);
@@ -6739,7 +7356,8 @@ qla2x00_timer(struct timer_list *t)
test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) ||
test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) ||
test_bit(VP_DPC_NEEDED, &vha->dpc_flags) ||
test_bit(RELOGIN_NEEDED, &vha->dpc_flags))) {
test_bit(RELOGIN_NEEDED, &vha->dpc_flags) ||
test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags))) {
ql_dbg(ql_dbg_timer, vha, 0x600b,
"isp_abort_needed=%d loop_resync_needed=%d "
"fcport_update_needed=%d start_dpc=%d "
@@ -6752,12 +7370,13 @@ qla2x00_timer(struct timer_list *t)
ql_dbg(ql_dbg_timer, vha, 0x600c,
"beacon_blink_needed=%d isp_unrecoverable=%d "
"fcoe_ctx_reset_needed=%d vp_dpc_needed=%d "
"relogin_needed=%d.\n",
"relogin_needed=%d, Process_purex_iocb=%d.\n",
test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags),
test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags),
test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags),
test_bit(VP_DPC_NEEDED, &vha->dpc_flags),
test_bit(RELOGIN_NEEDED, &vha->dpc_flags));
test_bit(RELOGIN_NEEDED, &vha->dpc_flags),
test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags));
qla2xxx_wake_dpc(vha);
}
+8 -5
View File
@@ -2686,7 +2686,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
uint32_t sec_mask, rest_addr, fdata;
void *optrom = NULL;
dma_addr_t optrom_dma;
int rval;
int rval, ret;
struct secure_flash_update_block *sfub;
dma_addr_t sfub_dma;
uint32_t offset = faddr << 2;
@@ -2942,11 +2942,12 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
write_protect:
ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095,
"Protect flash...\n");
rval = qla24xx_protect_flash(vha);
if (rval) {
ret = qla24xx_protect_flash(vha);
if (ret) {
qla81xx_fac_semaphore_access(vha, FAC_SEMAPHORE_UNLOCK);
ql_log(ql_log_warn, vha, 0x7099,
"Failed protect flash\n");
rval = QLA_COMMAND_ERROR;
}
if (reset_to_rom == true) {
@@ -2954,10 +2955,12 @@ write_protect:
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
rval = qla2x00_wait_for_hba_online(vha);
if (rval != QLA_SUCCESS)
ret = qla2x00_wait_for_hba_online(vha);
if (ret != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0xffff,
"Adapter did not come out of reset\n");
rval = QLA_COMMAND_ERROR;
}
}
done:
+5 -5
View File
@@ -1773,7 +1773,7 @@ static int qlt_build_abts_resp_iocb(struct qla_tgt_mgmt_cmd *mcmd)
qpair->req->outstanding_cmds[h] = (srb_t *)mcmd;
}
resp->handle = MAKE_HANDLE(qpair->req->id, h);
resp->handle = make_handle(qpair->req->id, h);
resp->entry_type = ABTS_RESP_24XX;
resp->entry_count = 1;
resp->nport_handle = abts->nport_handle;
@@ -2610,7 +2610,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
} else
qpair->req->outstanding_cmds[h] = (srb_t *)prm->cmd;
pkt->handle = MAKE_HANDLE(qpair->req->id, h);
pkt->handle = make_handle(qpair->req->id, h);
pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
@@ -3124,7 +3124,7 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm)
} else
qpair->req->outstanding_cmds[h] = (srb_t *)prm->cmd;
pkt->handle = MAKE_HANDLE(qpair->req->id, h);
pkt->handle = make_handle(qpair->req->id, h);
pkt->handle |= CTIO_COMPLETION_HANDLE_MARK;
pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id);
pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT);
@@ -4807,11 +4807,11 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
qla24xx_post_newsess_work(vha, &port_id,
iocb->u.isp24.port_name,
iocb->u.isp24.u.plogi.node_name,
pla, FC4_TYPE_UNKNOWN);
pla, 0);
else
qla24xx_post_newsess_work(vha, &port_id,
iocb->u.isp24.port_name, NULL,
pla, FC4_TYPE_UNKNOWN);
pla, 0);
goto out;
}
+9 -8
View File
@@ -870,7 +870,7 @@ bailout:
static void
qla27xx_time_stamp(struct qla27xx_fwdt_template *tmp)
{
tmp->capture_timestamp = jiffies;
tmp->capture_timestamp = cpu_to_le32(jiffies);
}
static void
@@ -882,9 +882,10 @@ qla27xx_driver_info(struct qla27xx_fwdt_template *tmp)
"%hhu.%hhu.%hhu.%hhu.%hhu.%hhu",
v+0, v+1, v+2, v+3, v+4, v+5) != 6);
tmp->driver_info[0] = v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0];
tmp->driver_info[1] = v[5] << 8 | v[4];
tmp->driver_info[2] = 0x12345678;
tmp->driver_info[0] = cpu_to_le32(
v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0]);
tmp->driver_info[1] = cpu_to_le32(v[5] << 8 | v[4]);
tmp->driver_info[2] = __constant_cpu_to_le32(0x12345678);
}
static void
@@ -894,10 +895,10 @@ qla27xx_firmware_info(struct scsi_qla_host *vha,
tmp->firmware_version[0] = vha->hw->fw_major_version;
tmp->firmware_version[1] = vha->hw->fw_minor_version;
tmp->firmware_version[2] = vha->hw->fw_subminor_version;
tmp->firmware_version[3] =
vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes;
tmp->firmware_version[4] =
vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0];
tmp->firmware_version[3] = cpu_to_le32(
vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes);
tmp->firmware_version[4] = cpu_to_le32(
vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0]);
}
static void
+2 -2
View File
@@ -18,11 +18,11 @@ struct __packed qla27xx_fwdt_template {
__le32 entry_count;
uint32_t template_version;
uint32_t capture_timestamp;
__le32 capture_timestamp;
uint32_t template_checksum;
uint32_t reserved_2;
uint32_t driver_info[3];
__le32 driver_info[3];
uint32_t saved_state[16];
+1 -1
View File
@@ -7,7 +7,7 @@
/*
* Driver version
*/
#define QLA2XXX_VERSION "10.01.00.22-k"
#define QLA2XXX_VERSION "10.01.00.25-k"
#define QLA_DRIVER_MAJOR_VER 10
#define QLA_DRIVER_MINOR_VER 1