Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2020-07-25 07:47:36 -07:00
22 changed files with 552 additions and 174 deletions
+3
View File
@@ -0,0 +1,3 @@
LINUXINCLUDE := $(PRE_CFLAGS) $(LINUXINCLUDE)
obj-m += rdma_reject.o
@@ -0,0 +1,11 @@
#include <linux/module.h>
#include <rdma/rdma_cm.h>
static struct rdma_cm_id id;
static int __init modinit(void)
{
return rdma_reject(&id, NULL, 0, 0);
}
module_init(modinit);
+1 -1
View File
@@ -6,7 +6,7 @@ config SCSI_QLA_FC
depends on NVME_FC || !NVME_FC
select FW_LOADER
select BTREE
---help---
help
This qla2xxx driver supports all QLogic Fibre Channel
PCI and PCIe host adapters.
+1 -2
View File
@@ -257,8 +257,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
/* validate fcp priority data */
if (!qla24xx_fcp_prio_cfg_valid(vha,
(struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) {
if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) {
bsg_reply->result = (DID_ERROR << 16);
ret = -EINVAL;
/* If buffer was invalidatic int
+36 -75
View File
@@ -11,10 +11,8 @@
* ----------------------------------------------------------------------
* | Level | Last Value Used | Holes |
* ----------------------------------------------------------------------
* | Module Init and Probe | 0x0193 | 0x0146 |
* | | | 0x015b-0x0160 |
* | | | 0x016e |
* | Mailbox commands | 0x1206 | 0x11a2-0x11ff |
* | Module Init and Probe | 0x0199 | |
* | Mailbox commands | 0x1206 | 0x11a5-0x11ff |
* | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a |
* | | | 0x211c-0x2128 |
@@ -26,11 +24,7 @@
* | | | 0x3036,0x3038 |
* | | | 0x303a |
* | DPC Thread | 0x4023 | 0x4002,0x4013 |
* | Async Events | 0x5090 | 0x502b-0x502f |
* | | | 0x5047 |
* | | | 0x5084,0x5075 |
* | | | 0x503d,0x5044 |
* | | | 0x505f |
* | Async Events | 0x509c | |
* | Timer Routines | 0x6012 | |
* | User Space Interactions | 0x70e3 | 0x7018,0x702e |
* | | | 0x7020,0x7024 |
@@ -1063,7 +1057,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha)
}
if (rval == QLA_SUCCESS)
qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
qla2xxx_copy_queues(ha, &fw->queue_dump[0]);
qla2xxx_dump_post_process(base_vha, rval);
}
@@ -2447,6 +2441,23 @@ qla83xx_fw_dump_failed_0:
/* Driver Debug Functions. */
/****************************************************************************/
/* Write the debug message prefix into @pbuf. */
static void ql_dbg_prefix(char *pbuf, int pbuf_size,
const scsi_qla_host_t *vha, uint msg_id)
{
if (vha) {
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> [<dev-name>]-<msg-id>:<host>: */
snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%ld: ", QL_MSGHDR,
dev_name(&(pdev->dev)), msg_id, vha->host_no);
} else {
/* <module-name> [<dev-name>]-<msg-id>: : */
snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR,
"0000:00:00.0", msg_id);
}
}
/*
* This function is for formatting and logging debug information.
* It is to be used when vha is available. It formats the message
@@ -2465,41 +2476,19 @@ ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
{
va_list va;
struct va_format vaf;
char pbuf[64];
va_start(va, fmt);
vaf.fmt = fmt;
vaf.va = &va;
if (!ql_mask_match(level)) {
char pbuf[64];
ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id);
if (vha != NULL) {
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> <msg-id>:<host> Message */
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ",
QL_MSGHDR, dev_name(&(pdev->dev)), id,
vha->host_no);
} else {
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
QL_MSGHDR, "0000:00:00.0", id);
}
pbuf[sizeof(pbuf) - 1] = 0;
if (!ql_mask_match(level))
trace_ql_dbg_log(pbuf, &vaf);
va_end(va);
return;
}
if (vha != NULL) {
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> <pci-name> <msg-id>:<host> Message */
pr_warn("%s [%s]-%04x:%ld: %pV",
QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
vha->host_no, &vaf);
} else {
pr_warn("%s [%s]-%04x: : %pV",
QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf);
}
else
pr_warn("%s%pV", pbuf, &vaf);
va_end(va);
@@ -2524,6 +2513,7 @@ ql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
{
va_list va;
struct va_format vaf;
char pbuf[128];
if (pdev == NULL)
return;
@@ -2535,9 +2525,8 @@ ql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
vaf.fmt = fmt;
vaf.va = &va;
/* <module-name> <dev-name>:<msg-id> Message */
pr_warn("%s [%s]-%04x: : %pV",
QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, &vaf);
ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id + ql_dbg_offset);
pr_warn("%s%pV", pbuf, &vaf);
va_end(va);
}
@@ -2565,16 +2554,7 @@ ql_log(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
if (level > ql_errlev)
return;
if (vha != NULL) {
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> <msg-id>:<host> Message */
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ",
QL_MSGHDR, dev_name(&(pdev->dev)), id, vha->host_no);
} else {
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
QL_MSGHDR, "0000:00:00.0", id);
}
pbuf[sizeof(pbuf) - 1] = 0;
ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id);
va_start(va, fmt);
@@ -2625,10 +2605,7 @@ ql_log_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...)
if (level > ql_errlev)
return;
/* <module-name> <dev-name>:<msg-id> Message */
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
QL_MSGHDR, dev_name(&(pdev->dev)), id);
pbuf[sizeof(pbuf) - 1] = 0;
ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id);
va_start(va, fmt);
@@ -2679,7 +2656,6 @@ ql_dump_regs(uint level, scsi_qla_host_t *vha, uint id)
"mbox[%d] %#04x\n", i, rd_reg_word(mbx_reg));
}
void
ql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf,
uint size)
@@ -2724,16 +2700,7 @@ ql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
if (level > ql_errlev)
return;
if (qpair != NULL) {
const struct pci_dev *pdev = qpair->pdev;
/* <module-name> <msg-id>:<host> Message */
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: ",
QL_MSGHDR, dev_name(&(pdev->dev)), id);
} else {
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
QL_MSGHDR, "0000:00:00.0", id);
}
pbuf[sizeof(pbuf) - 1] = 0;
ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL, id);
va_start(va, fmt);
@@ -2777,6 +2744,7 @@ ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
{
va_list va;
struct va_format vaf;
char pbuf[128];
if (!ql_mask_match(level))
return;
@@ -2786,16 +2754,9 @@ ql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id,
vaf.fmt = fmt;
vaf.va = &va;
if (qpair != NULL) {
const struct pci_dev *pdev = qpair->pdev;
/* <module-name> <pci-name> <msg-id>:<host> Message */
pr_warn("%s [%s]-%04x: %pV",
QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
&vaf);
} else {
pr_warn("%s [%s]-%04x: : %pV",
QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf);
}
ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL,
id + ql_dbg_offset);
pr_warn("%s%pV", pbuf, &vaf);
va_end(va);
+1
View File
@@ -53,6 +53,7 @@ struct qla2100_fw_dump {
__be16 fpm_b0_reg[64];
__be16 fpm_b1_reg[64];
__be16 risc_ram[0xf000];
u8 queue_dump[];
};
struct qla24xx_fw_dump {
+62 -2
View File
@@ -56,6 +56,8 @@
#error
#endif
#include <uapi/scsi/fc/fc_els.h>
/* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
typedef struct {
uint8_t domain;
@@ -1079,6 +1081,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define MBA_LIP_F8 0x8016 /* Received a LIP F8. */
#define MBA_LOOP_INIT_ERR 0x8017 /* Loop Initialization Error. */
#define MBA_FABRIC_AUTH_REQ 0x801b /* Fabric Authentication Required. */
#define MBA_CONGN_NOTI_RECV 0x801e /* Congestion Notification Received */
#define MBA_SCSI_COMPLETION 0x8020 /* SCSI Command Complete. */
#define MBA_CTIO_COMPLETION 0x8021 /* CTIO Complete. */
#define MBA_IP_COMPLETION 0x8022 /* IP Transmit Command Complete. */
@@ -1330,7 +1333,6 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#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
@@ -1535,6 +1537,25 @@ typedef struct {
uint8_t reserved_3[26];
} init_cb_t;
/* Special Features Control Block */
struct init_sf_cb {
uint8_t format;
uint8_t reserved0;
/*
* BIT 15-14 = Reserved
* BIT_13 = SAN Congestion Management (1 - Enabled, 0 - Disabled)
* BIT_12 = Remote Write Optimization (1 - Enabled, 0 - Disabled)
* BIT 11-0 = Reserved
*/
uint16_t flags;
uint8_t reserved1[32];
uint16_t discard_OHRB_timeout_value;
uint16_t remote_write_opt_queue_num;
uint8_t reserved2[40];
uint8_t scm_related_parameter[16];
uint8_t reserved3[32];
};
/*
* Get Link Status mailbox command return buffer.
*/
@@ -2208,6 +2229,8 @@ typedef struct {
struct dsd64 rsp_dsd;
} ms_iocb_entry_t;
#define SCM_EDC_ACC_RECEIVED BIT_6
#define SCM_RDF_ACC_RECEIVED BIT_7
/*
* ISP queue - Mailbox Command entry structure definition.
@@ -3878,6 +3901,12 @@ struct qla_hw_data {
uint32_t n2n_bigger:1;
uint32_t secure_adapter:1;
uint32_t secure_fw:1;
/* Supported by Adapter */
uint32_t scm_supported_a:1;
/* Supported by Firmware */
uint32_t scm_supported_f:1;
/* Enabled in Driver */
uint32_t scm_enabled:1;
} flags;
uint16_t max_exchg;
@@ -4195,6 +4224,13 @@ struct qla_hw_data {
int init_cb_size;
dma_addr_t ex_init_cb_dma;
struct ex_init_cb_81xx *ex_init_cb;
dma_addr_t sf_init_cb_dma;
struct init_sf_cb *sf_init_cb;
void *scm_fpin_els_buff;
uint64_t scm_fpin_els_buff_size;
bool scm_fpin_valid;
bool scm_fpin_payload_size;
void *async_pd;
dma_addr_t async_pd_dma;
@@ -4257,6 +4293,12 @@ struct qla_hw_data {
#define FW_ATTR_H_NVME BIT_10
#define FW_ATTR_H_NVME_UPDATED BIT_14
/* About firmware SCM support */
#define FW_ATTR_EXT0_SCM_SUPPORTED BIT_12
/* Brocade fabric attached */
#define FW_ATTR_EXT0_SCM_BROCADE 0x00001000
/* Cisco fabric attached */
#define FW_ATTR_EXT0_SCM_CISCO 0x00002000
uint16_t fw_attributes_ext[2];
uint32_t fw_memory_size;
uint32_t fw_transfer_size;
@@ -4549,15 +4591,31 @@ struct active_regions {
#define QLA_SET_DATA_RATE_NOLR 1
#define QLA_SET_DATA_RATE_LR 2 /* Set speed and initiate LR */
#define QLA_DEFAULT_PAYLOAD_SIZE 64
/*
* This item might be allocated with a size > sizeof(struct purex_item).
* The "size" variable gives the size of the payload (which
* is variable) starting at "iocb".
*/
struct purex_item {
struct list_head list;
struct scsi_qla_host *vha;
void (*process_item)(struct scsi_qla_host *vha, void *pkt);
void (*process_item)(struct scsi_qla_host *vha,
struct purex_item *pkt);
atomic_t in_use;
uint16_t size;
struct {
uint8_t iocb[64];
} iocb;
};
#define SCM_FLAG_RDF_REJECT 0x00
#define SCM_FLAG_RDF_COMPLETED 0x01
#define QLA_CON_PRIMITIVE_RECEIVED 0x1
#define QLA_CONGESTION_ARB_WARNING 0x1
#define QLA_CONGESTION_ARB_ALARM 0X2
/*
* Qlogic scsi host structure
*/
@@ -4752,6 +4810,7 @@ typedef struct scsi_qla_host {
struct list_head head;
spinlock_t lock;
} purex_list;
struct purex_item default_item;
struct name_list_extended gnl;
/* Count of active session/fcport */
@@ -4765,6 +4824,7 @@ typedef struct scsi_qla_host {
__le16 dport_data[4];
struct list_head gpnid_list;
struct fab_scan scan;
uint8_t scm_fabric_connection_flags;
unsigned int irq_offset;
} scsi_qla_host_t;
+6 -2
View File
@@ -622,7 +622,7 @@ struct sts_entry_24xx {
__le32 residual_len; /* FW calc residual transfer length. */
union {
uint16_t reserved_1;
__le16 reserved_1;
__le16 nvme_rsp_pyld_len;
};
@@ -735,6 +735,8 @@ struct ct_entry_24xx {
struct dsd64 dsd[2];
};
#define PURX_ELS_HEADER_SIZE 0x18
/*
* ISP queue - PUREX IOCB entry structure definition
*/
@@ -2032,7 +2034,9 @@ struct nvram_81xx {
* BIT 0 = Extended BB credits for LR
* BIT 1 = Virtual Fabric Enable
* BIT 2-5 = Distance Support if BIT 0 is on
* BIT 6-15 = Unused
* BIT 6 = Prefer FCP
* BIT 7 = SCM Disabled if BIT is set (1)
* BIT 8-15 = Unused
*/
uint16_t enhanced_features;
+3 -1
View File
@@ -127,6 +127,7 @@ int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *);
void qla_rscn_replay(fc_port_t *fcport);
void qla24xx_free_purex_item(struct purex_item *item);
extern bool qla24xx_risc_firmware_invalid(uint32_t *);
/*
@@ -233,7 +234,8 @@ 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);
void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
struct purex_item *pkt);
/*
* Global Functions in qla_mid.c source file.
+29 -19
View File
@@ -3749,7 +3749,7 @@ enable_82xx_npiv:
}
/* Enable PUREX PASSTHRU */
if (ql2xrdpenable)
if (ql2xrdpenable || ha->flags.scm_supported_f)
qla25xx_set_els_cmds_supported(vha);
} else
goto failed;
@@ -3962,7 +3962,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_8;
}
if (ql2xrdpenable)
if (ql2xrdpenable || ha->flags.scm_supported_f)
ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
/* Enable Async 8130/8131 events -- transceiver insertion/removal */
@@ -6996,36 +6996,41 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
static int
qla2x00_restart_isp(scsi_qla_host_t *vha)
{
int status = 0;
int status;
struct qla_hw_data *ha = vha->hw;
/* If firmware needs to be loaded */
if (qla2x00_isp_firmware(vha)) {
vha->flags.online = 0;
status = ha->isp_ops->chip_diag(vha);
if (!status)
status = qla2x00_setup_chip(vha);
if (status)
return status;
status = qla2x00_setup_chip(vha);
if (status)
return status;
}
if (!status && !(status = qla2x00_init_rings(vha))) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
ha->flags.chip_reset_done = 1;
status = qla2x00_init_rings(vha);
if (status)
return status;
/* Initialize the queues in use */
qla25xx_init_queues(ha);
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
ha->flags.chip_reset_done = 1;
status = qla2x00_fw_ready(vha);
if (!status) {
/* Issue a marker after FW becomes ready. */
qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
/* Initialize the queues in use */
qla25xx_init_queues(ha);
status = qla2x00_fw_ready(vha);
if (status) {
/* if no cable then assume it's good */
if ((vha->device_flags & DFLG_NO_CABLE))
status = 0;
return vha->device_flags & DFLG_NO_CABLE ? 0 : status;
}
return (status);
/* Issue a marker after FW becomes ready. */
qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
return 0;
}
static int
@@ -8514,6 +8519,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->node_name[0] &= 0xF0;
}
if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
if ((nv->enhanced_features & BIT_7) == 0)
ha->flags.scm_supported_a = 1;
}
/* Set host adapter parameters. */
ha->flags.disable_risc_code_load = 0;
ha->flags.enable_lip_reset = 0;
+1 -1
View File
@@ -19,7 +19,7 @@
* Continuation Type 1 IOCBs to allocate.
*
* @vha: HA context
* @dsds: number of data segment decriptors needed
* @dsds: number of data segment descriptors needed
*
* Returns the number of IOCB entries needed to store @dsds.
*/
+5 -5
View File
@@ -44,7 +44,7 @@ qla2x00_get_cmd_direction(srb_t *sp)
* qla2x00_calc_iocbs_32() - Determine number of Command Type 2 and
* Continuation Type 0 IOCBs to allocate.
*
* @dsds: number of data segment decriptors needed
* @dsds: number of data segment descriptors needed
*
* Returns the number of IOCB entries needed to store @dsds.
*/
@@ -66,7 +66,7 @@ qla2x00_calc_iocbs_32(uint16_t dsds)
* qla2x00_calc_iocbs_64() - Determine number of Command Type 3 and
* Continuation Type 1 IOCBs to allocate.
*
* @dsds: number of data segment decriptors needed
* @dsds: number of data segment descriptors needed
*
* Returns the number of IOCB entries needed to store @dsds.
*/
@@ -669,7 +669,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
* qla24xx_calc_dsd_lists() - Determine number of DSD list required
* for Command Type 6.
*
* @dsds: number of data segment decriptors needed
* @dsds: number of data segment descriptors needed
*
* Returns the number of dsd list needed to store @dsds.
*/
@@ -2311,8 +2311,8 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
pkt = req->ring_ptr;
memset(pkt, 0, REQUEST_ENTRY_SIZE);
if (IS_QLAFX00(ha)) {
wrt_reg_byte((void __iomem *)&pkt->entry_count, req_cnt);
wrt_reg_word((void __iomem *)&pkt->handle, handle);
wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);
} else {
pkt->entry_count = req_cnt;
pkt->handle = handle;
+249 -41
View File
@@ -34,6 +34,31 @@ static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
sts_entry_t *);
static void qla27xx_process_purex_fpin(struct scsi_qla_host *vha,
struct purex_item *item);
static struct purex_item *qla24xx_alloc_purex_item(scsi_qla_host_t *vha,
uint16_t size);
static struct purex_item *qla24xx_copy_std_pkt(struct scsi_qla_host *vha,
void *pkt);
static struct purex_item *qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha,
void **pkt, struct rsp_que **rsp);
static void
qla27xx_process_purex_fpin(struct scsi_qla_host *vha, struct purex_item *item)
{
void *pkt = &item->iocb;
uint16_t pkt_size = item->size;
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x508d,
"%s: Enter\n", __func__);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x508e,
"-------- ELS REQ -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x508f,
pkt, pkt_size);
fc_host_fpin_rcv(vha->host, pkt_size, (char *)pkt);
}
const char *const port_state_str[] = {
"Unknown",
@@ -43,35 +68,11 @@ 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)
qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
{
struct abts_entry_24xx *abts = pkt;
struct abts_entry_24xx *abts =
(struct abts_entry_24xx *)&pkt->iocb;
struct qla_hw_data *ha = vha->hw;
struct els_entry_24xx *rsp_els;
struct abts_entry_24xx *abts_rsp;
@@ -801,6 +802,179 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
}
}
static struct purex_item *
qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
{
struct purex_item *item = NULL;
uint8_t item_hdr_size = sizeof(*item);
if (size > QLA_DEFAULT_PAYLOAD_SIZE) {
item = kzalloc(item_hdr_size +
(size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC);
} else {
if (atomic_inc_return(&vha->default_item.in_use) == 1) {
item = &vha->default_item;
goto initialize_purex_header;
} else {
item = kzalloc(item_hdr_size, GFP_ATOMIC);
}
}
if (!item) {
ql_log(ql_log_warn, vha, 0x5092,
">> Failed allocate purex list item.\n");
return NULL;
}
initialize_purex_header:
item->vha = vha;
item->size = size;
return item;
}
static void
qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
void (*process_item)(struct scsi_qla_host *vha,
struct purex_item *pkt))
{
struct purex_list *list = &vha->purex_list;
ulong flags;
pkt->process_item = process_item;
spin_lock_irqsave(&list->lock, flags);
list_add_tail(&pkt->list, &list->head);
spin_unlock_irqrestore(&list->lock, flags);
set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
}
/**
* qla24xx_copy_std_pkt() - Copy over purex ELS which is
* contained in a single IOCB.
* purex packet.
* @vha: SCSI driver HA context
* @pkt: ELS packet
*/
static struct purex_item *
qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
{
struct purex_item *item;
item = qla24xx_alloc_purex_item(vha,
QLA_DEFAULT_PAYLOAD_SIZE);
if (!item)
return item;
memcpy(&item->iocb, pkt, sizeof(item->iocb));
return item;
}
/**
* qla27xx_copy_fpin_pkt() - Copy over fpin packets that can
* span over multiple IOCBs.
* @vha: SCSI driver HA context
* @pkt: ELS packet
* @rsp: Response queue
*/
static struct purex_item *
qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
struct rsp_que **rsp)
{
struct purex_entry_24xx *purex = *pkt;
struct rsp_que *rsp_q = *rsp;
sts_cont_entry_t *new_pkt;
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
uint16_t buffer_copy_offset = 0;
uint16_t entry_count, entry_count_remaining;
struct purex_item *item;
void *fpin_pkt = NULL;
total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF)
- PURX_ELS_HEADER_SIZE;
pending_bytes = total_bytes;
entry_count = entry_count_remaining = purex->entry_count;
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
sizeof(purex->els_frame_payload) : pending_bytes;
ql_log(ql_log_info, vha, 0x509a,
"FPIN ELS, frame_size 0x%x, entry count %d\n",
total_bytes, entry_count);
item = qla24xx_alloc_purex_item(vha, total_bytes);
if (!item)
return item;
fpin_pkt = &item->iocb;
memcpy(fpin_pkt, &purex->els_frame_payload[0], no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
--entry_count_remaining;
((response_t *)purex)->signature = RESPONSE_PROCESSED;
wmb();
do {
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
ql_dbg(ql_dbg_async, vha, 0x5084,
"Ran out of IOCBs, partial data 0x%x\n",
buffer_copy_offset);
cpu_relax();
continue;
}
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
ql_log(ql_log_warn, vha, 0x507a,
"Unexpected IOCB type, partial data 0x%x\n",
buffer_copy_offset);
break;
}
rsp_q->ring_index++;
if (rsp_q->ring_index == rsp_q->length) {
rsp_q->ring_index = 0;
rsp_q->ring_ptr = rsp_q->ring;
} else {
rsp_q->ring_ptr++;
}
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
sizeof(new_pkt->data) : pending_bytes;
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
memcpy(((uint8_t *)fpin_pkt +
buffer_copy_offset), new_pkt->data,
no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
--entry_count_remaining;
} else {
ql_log(ql_log_warn, vha, 0x5044,
"Attempt to copy more that we got, optimizing..%x\n",
buffer_copy_offset);
memcpy(((uint8_t *)fpin_pkt +
buffer_copy_offset), new_pkt->data,
total_bytes - buffer_copy_offset);
}
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
wmb();
}
if (pending_bytes != 0 || entry_count_remaining != 0) {
ql_log(ql_log_fatal, vha, 0x508b,
"Dropping partial FPIN, underrun bytes = 0x%x, entry cnts 0x%x\n",
total_bytes, entry_count_remaining);
qla24xx_free_purex_item(item);
return NULL;
}
} while (entry_count_remaining > 0);
host_to_fcp_swap((uint8_t *)&item->iocb, total_bytes);
return item;
}
/**
* qla2x00_async_event() - Process aynchronous events.
* @vha: SCSI driver HA context
@@ -1314,6 +1488,19 @@ global_port_update:
qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry);
}
break;
case MBA_CONGN_NOTI_RECV:
if (!ha->flags.scm_enabled ||
mb[1] != QLA_CON_PRIMITIVE_RECEIVED)
break;
if (mb[2] == QLA_CONGESTION_ARB_WARNING) {
ql_dbg(ql_dbg_async, vha, 0x509b,
"Congestion Warning %04x %04x.\n", mb[1], mb[2]);
} else if (mb[2] == QLA_CONGESTION_ARB_ALARM) {
ql_log(ql_log_warn, vha, 0x509b,
"Congestion Alarm %04x %04x.\n", mb[1], mb[2]);
}
break;
/* case MBA_RIO_RESPONSE: */
case MBA_ZIO_RESPONSE:
ql_dbg(ql_dbg_async, vha, 0x5015,
@@ -3264,6 +3451,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
{
struct sts_entry_24xx *pkt;
struct qla_hw_data *ha = vha->hw;
struct purex_entry_24xx *purex_entry;
struct purex_item *pure_item;
if (!ha->flags.fw_started)
return;
@@ -3315,8 +3504,11 @@ process_err:
break;
case ABTS_RECV_24XX:
if (qla_ini_mode_enabled(vha)) {
qla24xx_purex_iocb(vha, pkt,
qla24xx_process_abts);
pure_item = qla24xx_copy_std_pkt(vha, pkt);
if (!pure_item)
break;
qla24xx_queue_purex_item(vha, pure_item,
qla24xx_process_abts);
break;
}
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
@@ -3364,24 +3556,40 @@ process_err:
(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]);
purex_entry = (void *)pkt;
switch (purex_entry->els_frame_payload[3]) {
case ELS_RDP:
pure_item = qla24xx_copy_std_pkt(vha, pkt);
if (!pure_item)
break;
qla24xx_queue_purex_item(vha, pure_item,
qla24xx_process_purex_rdp);
break;
case ELS_FPIN:
if (!vha->hw->flags.scm_enabled) {
ql_log(ql_log_warn, vha, 0x5094,
"SCM not active for this port\n");
break;
}
pure_item = qla27xx_copy_fpin_pkt(vha,
(void **)&pkt, &rsp);
if (!pure_item)
break;
qla24xx_queue_purex_item(vha, pure_item,
qla27xx_process_purex_fpin);
break;
default:
ql_log(ql_log_warn, vha, 0x509c,
"Discarding ELS Request opcode 0x%x\n",
purex_entry->els_frame_payload[3]);
}
qla24xx_purex_iocb(vha, pkt, qla24xx_process_purex_rdp);
break;
}
default:
/* Type Not Supported. */
ql_dbg(ql_dbg_async, vha, 0x5042,
"Received unknown response pkt type %x "
"entry status=%x.\n",
pkt->entry_type, pkt->entry_status);
"Received unknown response pkt type 0x%x entry status=%x.\n",
pkt->entry_type, pkt->entry_status);
break;
}
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
+57 -7
View File
@@ -59,6 +59,7 @@ static struct rom_cmd {
{ MBC_IOCB_COMMAND_A64 },
{ MBC_GET_ADAPTER_LOOP_ID },
{ MBC_READ_SFP },
{ MBC_SET_RNID_PARAMS },
{ MBC_GET_RNID_PARAMS },
{ MBC_GET_SET_ZIO_THRESHOLD },
};
@@ -1124,6 +1125,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
(ha->flags.secure_fw) ? "Supported" :
"Not Supported");
}
if (ha->flags.scm_supported_a &&
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {
ha->flags.scm_supported_f = 1;
memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb));
ha->sf_init_cb->flags |= BIT_13;
}
ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",
(ha->flags.scm_supported_f) ? "Supported" :
"Not Supported");
}
failed:
@@ -1633,8 +1644,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
if (IS_FWI2_CAPABLE(vha->hw))
mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw))
if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {
mcp->in_mb |= MBX_15;
mcp->out_mb |= MBX_7|MBX_21|MBX_22|MBX_23;
}
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -1687,8 +1701,22 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
}
}
if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw))
if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {
vha->bbcr = mcp->mb[15];
if (mcp->mb[7] & SCM_EDC_ACC_RECEIVED) {
ql_log(ql_log_info, vha, 0x11a4,
"SCM: EDC ELS completed, flags 0x%x\n",
mcp->mb[21]);
}
if (mcp->mb[7] & SCM_RDF_ACC_RECEIVED) {
vha->hw->flags.scm_enabled = 1;
vha->scm_fabric_connection_flags |=
SCM_FLAG_RDF_COMPLETED;
ql_log(ql_log_info, vha, 0x11a5,
"SCM: RDF ELS completed, flags 0x%x\n",
mcp->mb[23]);
}
}
}
return rval;
@@ -1801,6 +1829,17 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
mcp->mb[14] = sizeof(*ha->ex_init_cb);
mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
}
if (ha->flags.scm_supported_f) {
mcp->mb[1] |= BIT_1;
mcp->mb[16] = MSW(ha->sf_init_cb_dma);
mcp->mb[17] = LSW(ha->sf_init_cb_dma);
mcp->mb[18] = MSW(MSD(ha->sf_init_cb_dma));
mcp->mb[19] = LSW(MSD(ha->sf_init_cb_dma));
mcp->mb[15] = sizeof(*ha->sf_init_cb);
mcp->out_mb |= MBX_19|MBX_18|MBX_17|MBX_16|MBX_15;
}
/* 1 and 2 should normally be captured. */
mcp->in_mb = MBX_2|MBX_1|MBX_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
@@ -4866,6 +4905,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
return rval;
}
#define PUREX_CMD_COUNT 2
int
qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
{
@@ -4874,12 +4914,12 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
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;
uint8_t cmd_opcode[PUREX_CMD_COUNT];
uint8_t i, index, purex_bit;
struct qla_hw_data *ha = vha->hw;
if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha))
if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return QLA_SUCCESS;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
@@ -4893,7 +4933,17 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
return QLA_MEMORY_ALLOC_FAILED;
}
els_cmd_map[index] |= 1 << bit;
memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
/* List of Purex ELS */
cmd_opcode[0] = ELS_FPIN;
cmd_opcode[1] = ELS_RDP;
for (i = 0; i < PUREX_CMD_COUNT; i++) {
index = cmd_opcode[i] / 8;
purex_bit = cmd_opcode[i] % 8;
els_cmd_map[index] |= 1 << purex_bit;
}
mcp->mb[0] = MBC_SET_RNID_PARAMS;
mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
+8 -12
View File
@@ -1014,26 +1014,21 @@ qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)
static int
qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)
{
long timeout = 0;
uint32_t done = 1 ;
uint32_t val;
int ret = 0;
int i, ret;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
while ((done != 0) && (ret == 0)) {
for (i = 0; i < 50000; i++) {
ret = qla82xx_read_status_reg(ha, &val);
done = val & 1;
timeout++;
if (ret < 0 || (val & 1) == 0)
return ret;
udelay(10);
cond_resched();
if (timeout >= 50000) {
ql_log(ql_log_warn, vha, 0xb00d,
"Timeout reached waiting for write finish.\n");
return -1;
}
}
return ret;
ql_log(ql_log_warn, vha, 0xb00d,
"Timeout reached waiting for write finish.\n");
return -1;
}
static int
@@ -1220,6 +1215,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
* Offset 4: Offset and number of addr/value pairs
* that present in CRB initialize sequence
*/
n = 0;
if (qla82xx_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafeUL ||
qla82xx_rom_fast_read(ha, 4, &n) != 0) {
ql_log(ql_log_fatal, vha, 0x006e,
+32 -4
View File
@@ -4266,6 +4266,16 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
"ex_init_cb=%p.\n", ha->ex_init_cb);
}
/* Get consistent memory allocated for Special Features-CB. */
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ha->sf_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
&ha->sf_init_cb_dma);
if (!ha->sf_init_cb)
goto fail_sf_init_cb;
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199,
"sf_init_cb=%p.\n", ha->sf_init_cb);
}
INIT_LIST_HEAD(&ha->gbl_dsd_list);
/* Get consistent memory allocated for Async Port-Database. */
@@ -4319,6 +4329,8 @@ fail_sfp_data:
fail_loop_id_map:
dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
fail_async_pd:
dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma);
fail_sf_init_cb:
dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
fail_ex_init_cb:
kfree(ha->npiv_info);
@@ -4741,6 +4753,10 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->ms_iocb = NULL;
ha->ms_iocb_dma = 0;
if (ha->sf_init_cb)
dma_pool_free(ha->s_dma_pool,
ha->sf_init_cb, ha->sf_init_cb_dma);
if (ha->ex_init_cb)
dma_pool_free(ha->s_dma_pool,
ha->ex_init_cb, ha->ex_init_cb_dma);
@@ -4828,6 +4844,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
kfree(ha->swl);
ha->swl = NULL;
kfree(ha->loop_id_map);
ha->sf_init_cb = NULL;
ha->sf_init_cb_dma = 0;
ha->loop_id_map = NULL;
}
@@ -5945,10 +5963,12 @@ qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
* vha: SCSI qla host
* purex: RDP request received by HBA
*/
void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
struct purex_item *item)
{
struct qla_hw_data *ha = vha->hw;
struct purex_entry_24xx *purex = pkt;
struct purex_entry_24xx *purex =
(struct purex_entry_24xx *)&item->iocb;
dma_addr_t rsp_els_dma;
dma_addr_t rsp_payload_dma;
dma_addr_t stat_dma;
@@ -6358,6 +6378,14 @@ dealloc:
rsp_els, rsp_els_dma);
}
void qla24xx_free_purex_item(struct purex_item *item)
{
if (item == &item->vha->default_item)
memset(&item->vha->default_item, 0, sizeof(struct purex_item));
else
kfree(item);
}
void qla24xx_process_purex_list(struct purex_list *list)
{
struct list_head head = LIST_HEAD_INIT(head);
@@ -6370,8 +6398,8 @@ void qla24xx_process_purex_list(struct purex_list *list)
list_for_each_entry_safe(item, next, &head, list) {
list_del(&item->list);
item->process_item(item->vha, &item->iocb);
kfree(item);
item->process_item(item->vha, item);
qla24xx_free_purex_item(item);
}
}
+2 -2
View File
@@ -285,7 +285,7 @@ struct fcp_hdr {
__be16 ox_id;
uint16_t rx_id;
__le32 parameter;
} __packed;
};
struct fcp_hdr_le {
le_id_t d_id;
@@ -300,7 +300,7 @@ struct fcp_hdr_le {
__le16 rx_id;
__le16 ox_id;
__le32 parameter;
} __packed;
};
#define F_CTL_EXCH_CONTEXT_RESP BIT_23
#define F_CTL_SEQ_CONTEXT_RESIP BIT_22
+10
View File
@@ -2032,6 +2032,16 @@ enum {
#define wwn_to_u64(wwn) get_unaligned_be64(wwn)
#endif
/* <uapi/scsi/fc/fc_els.h> */
/*
* See also commit 62e9dd177732 ("scsi: qla2xxx: Change in PUREX to handle FPIN
* ELS requests").
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
#define ELS_RDP 0x18
#endif
/* <target/target_core_base.h> */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
+3
View File
@@ -0,0 +1,3 @@
LINUXINCLUDE := $(PRE_CFLAGS) $(LINUXINCLUDE)
obj-m += add_one.o
+18
View File
@@ -0,0 +1,18 @@
#include <linux/module.h>
#include <rdma/rdma_cm.h>
static int add_one(struct ib_device *device)
{
return 0;
}
static struct ib_client test_client = {
.add = add_one,
};
static int __init modinit(void)
{
return ib_register_client(&test_client);
}
module_init(modinit);
+3
View File
@@ -0,0 +1,3 @@
LINUXINCLUDE := $(PRE_CFLAGS) $(LINUXINCLUDE)
obj-m += rdma_reject.o
+11
View File
@@ -0,0 +1,11 @@
#include <linux/module.h>
#include <rdma/rdma_cm.h>
static struct rdma_cm_id id;
static int __init modinit(void)
{
return rdma_reject(&id, NULL, 0, 0);
}
module_init(modinit);