mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 21:26:31 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
+118
-15
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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. */
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+101
-101
@@ -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(®->mailbox12) & BIT_0) {
|
||||
ql_log(ql_log_info, vha, 0xffff, "Adapter is Secure\n");
|
||||
if (RD_REG_DWORD(®->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
@@ -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
@@ -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(®24->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(®24->mailbox4);
|
||||
m[1] = RD_REG_WORD(®24->mailbox5);
|
||||
m[2] = RD_REG_WORD(®24->mailbox6);
|
||||
mbx = m[3] = RD_REG_WORD(®24->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(®24->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(®->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(®->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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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 = ∁
|
||||
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 = ∁
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user