mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 22:21:21 +00:00
[SCSI] qla2xxx: Add iIDMA support.
iIDMA (Intelligent Interleaved Direct Memory Access) allows for the HBA hardware to send FC frames at the rate at which they can be received by a target device. By taking advantage of the higher link rate, the HBA can maximize bandwidth utilization in a heterogeneous multi-speed SAN. Within a fabric topology, port speed detection is done via a Name Server command (GFPN_ID) followed by a Fabric Management command (GPSC). In an FCAL/N2N topology, port speed is based on the HBA link-rate. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
ee0ca6bab3
commit
d8b4521349
8 changed files with 401 additions and 12 deletions
|
@ -691,13 +691,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
|
||||||
uint32_t speed = 0;
|
uint32_t speed = 0;
|
||||||
|
|
||||||
switch (ha->link_data_rate) {
|
switch (ha->link_data_rate) {
|
||||||
case LDR_1GB:
|
case PORT_SPEED_1GB:
|
||||||
speed = 1;
|
speed = 1;
|
||||||
break;
|
break;
|
||||||
case LDR_2GB:
|
case PORT_SPEED_2GB:
|
||||||
speed = 2;
|
speed = 2;
|
||||||
break;
|
break;
|
||||||
case LDR_4GB:
|
case PORT_SPEED_4GB:
|
||||||
speed = 4;
|
speed = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,6 +608,7 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
#define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */
|
#define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */
|
||||||
#define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */
|
#define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */
|
||||||
|
#define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */
|
||||||
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
|
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
|
||||||
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
|
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
|
||||||
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
|
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
|
||||||
|
@ -1497,6 +1498,9 @@ typedef struct {
|
||||||
port_id_t d_id;
|
port_id_t d_id;
|
||||||
uint8_t node_name[WWN_SIZE];
|
uint8_t node_name[WWN_SIZE];
|
||||||
uint8_t port_name[WWN_SIZE];
|
uint8_t port_name[WWN_SIZE];
|
||||||
|
uint8_t fabric_port_name[WWN_SIZE];
|
||||||
|
uint16_t fp_speeds;
|
||||||
|
uint16_t fp_speed;
|
||||||
} sw_info_t;
|
} sw_info_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1524,6 +1528,9 @@ typedef struct fc_port {
|
||||||
uint16_t loop_id;
|
uint16_t loop_id;
|
||||||
uint16_t old_loop_id;
|
uint16_t old_loop_id;
|
||||||
|
|
||||||
|
uint8_t fabric_port_name[WWN_SIZE];
|
||||||
|
uint16_t fp_speed;
|
||||||
|
|
||||||
fc_port_type_t port_type;
|
fc_port_type_t port_type;
|
||||||
|
|
||||||
atomic_t state;
|
atomic_t state;
|
||||||
|
@ -1635,6 +1642,15 @@ typedef struct fc_port {
|
||||||
#define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
|
#define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
|
||||||
#define RSNN_NN_RSP_SIZE 16
|
#define RSNN_NN_RSP_SIZE 16
|
||||||
|
|
||||||
|
#define GFPN_ID_CMD 0x11C
|
||||||
|
#define GFPN_ID_REQ_SIZE (16 + 4)
|
||||||
|
#define GFPN_ID_RSP_SIZE (16 + 8)
|
||||||
|
|
||||||
|
#define GPSC_CMD 0x127
|
||||||
|
#define GPSC_REQ_SIZE (16 + 8)
|
||||||
|
#define GPSC_RSP_SIZE (16 + 2 + 2)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HBA attribute types.
|
* HBA attribute types.
|
||||||
*/
|
*/
|
||||||
|
@ -1748,7 +1764,7 @@ struct ct_sns_req {
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/* GA_NXT, GPN_ID, GNN_ID, GFT_ID */
|
/* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */
|
||||||
struct {
|
struct {
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
uint8_t port_id[3];
|
uint8_t port_id[3];
|
||||||
|
@ -1823,6 +1839,10 @@ struct ct_sns_req {
|
||||||
struct {
|
struct {
|
||||||
uint8_t port_name[8];
|
uint8_t port_name[8];
|
||||||
} dpa;
|
} dpa;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t port_name[8];
|
||||||
|
} gpsc;
|
||||||
} req;
|
} req;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1886,6 +1906,15 @@ struct ct_sns_rsp {
|
||||||
uint8_t port_name[8];
|
uint8_t port_name[8];
|
||||||
struct ct_fdmi_hba_attributes attrs;
|
struct ct_fdmi_hba_attributes attrs;
|
||||||
} ghat;
|
} ghat;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t port_name[8];
|
||||||
|
} gfpn_id;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint16_t speeds;
|
||||||
|
uint16_t speed;
|
||||||
|
} gpsc;
|
||||||
} rsp;
|
} rsp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2182,11 +2211,11 @@ typedef struct scsi_qla_host {
|
||||||
uint16_t max_public_loop_ids;
|
uint16_t max_public_loop_ids;
|
||||||
uint16_t min_external_loopid; /* First external loop Id */
|
uint16_t min_external_loopid; /* First external loop Id */
|
||||||
|
|
||||||
|
#define PORT_SPEED_UNKNOWN 0xFFFF
|
||||||
|
#define PORT_SPEED_1GB 0x00
|
||||||
|
#define PORT_SPEED_2GB 0x01
|
||||||
|
#define PORT_SPEED_4GB 0x03
|
||||||
uint16_t link_data_rate; /* F/W operating speed */
|
uint16_t link_data_rate; /* F/W operating speed */
|
||||||
#define LDR_1GB 0
|
|
||||||
#define LDR_2GB 1
|
|
||||||
#define LDR_4GB 3
|
|
||||||
#define LDR_UNKNOWN 0xFFFF
|
|
||||||
|
|
||||||
uint8_t current_topology;
|
uint8_t current_topology;
|
||||||
uint8_t prev_topology;
|
uint8_t prev_topology;
|
||||||
|
|
|
@ -208,6 +208,12 @@ qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t);
|
||||||
extern int
|
extern int
|
||||||
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
|
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global Function Prototypes in qla_isr.c source file.
|
* Global Function Prototypes in qla_isr.c source file.
|
||||||
*/
|
*/
|
||||||
|
@ -279,6 +285,8 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
|
||||||
extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
|
extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
|
||||||
extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
|
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_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 *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global Function Prototypes in qla_attr.c source file.
|
* Global Function Prototypes in qla_attr.c source file.
|
||||||
|
|
|
@ -687,7 +687,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
|
||||||
return (rval);
|
return (rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
|
* qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
|
||||||
* @ha: HA context
|
* @ha: HA context
|
||||||
|
@ -1647,3 +1646,189 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
|
||||||
|
* @ha: HA context
|
||||||
|
* @list: switch info entries to populate
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
uint16_t i;
|
||||||
|
|
||||||
|
ms_iocb_entry_t *ms_pkt;
|
||||||
|
struct ct_sns_req *ct_req;
|
||||||
|
struct ct_sns_rsp *ct_rsp;
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
|
||||||
|
/* Issue GFPN_ID */
|
||||||
|
memset(list[i].fabric_port_name, 0, WWN_SIZE);
|
||||||
|
|
||||||
|
/* Prepare common MS IOCB */
|
||||||
|
ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
|
||||||
|
GFPN_ID_RSP_SIZE);
|
||||||
|
|
||||||
|
/* Prepare CT request */
|
||||||
|
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
|
||||||
|
GFPN_ID_RSP_SIZE);
|
||||||
|
ct_rsp = &ha->ct_sns->p.rsp;
|
||||||
|
|
||||||
|
/* Prepare CT arguments -- port_id */
|
||||||
|
ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
|
||||||
|
ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
|
||||||
|
ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
|
||||||
|
|
||||||
|
/* Execute MS IOCB */
|
||||||
|
rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
|
||||||
|
sizeof(ms_iocb_entry_t));
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
/*EMPTY*/
|
||||||
|
DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB "
|
||||||
|
"failed (%d).\n", ha->host_no, rval));
|
||||||
|
} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
|
||||||
|
"GFPN_ID") != QLA_SUCCESS) {
|
||||||
|
rval = QLA_FUNCTION_FAILED;
|
||||||
|
} else {
|
||||||
|
/* Save fabric portname */
|
||||||
|
memcpy(list[i].fabric_port_name,
|
||||||
|
ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last device exit. */
|
||||||
|
if (list[i].d_id.b.rsvd_1 != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
|
||||||
|
uint32_t rsp_size)
|
||||||
|
{
|
||||||
|
struct ct_entry_24xx *ct_pkt;
|
||||||
|
|
||||||
|
ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
|
||||||
|
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
|
||||||
|
|
||||||
|
ct_pkt->entry_type = CT_IOCB_TYPE;
|
||||||
|
ct_pkt->entry_count = 1;
|
||||||
|
ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
|
||||||
|
ct_pkt->timeout = __constant_cpu_to_le16(59);
|
||||||
|
ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
|
||||||
|
ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
|
||||||
|
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
|
||||||
|
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
|
||||||
|
|
||||||
|
ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
|
||||||
|
ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
|
||||||
|
ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
|
||||||
|
|
||||||
|
ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
|
||||||
|
ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
|
||||||
|
ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
|
||||||
|
|
||||||
|
return ct_pkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline struct ct_sns_req *
|
||||||
|
qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
|
||||||
|
uint16_t rsp_size)
|
||||||
|
{
|
||||||
|
memset(ct_req, 0, sizeof(struct ct_sns_pkt));
|
||||||
|
|
||||||
|
ct_req->header.revision = 0x01;
|
||||||
|
ct_req->header.gs_type = 0xFA;
|
||||||
|
ct_req->header.gs_subtype = 0x01;
|
||||||
|
ct_req->command = cpu_to_be16(cmd);
|
||||||
|
ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
|
||||||
|
|
||||||
|
return ct_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
|
||||||
|
* @ha: HA context
|
||||||
|
* @list: switch info entries to populate
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
uint16_t i;
|
||||||
|
|
||||||
|
ms_iocb_entry_t *ms_pkt;
|
||||||
|
struct ct_sns_req *ct_req;
|
||||||
|
struct ct_sns_rsp *ct_rsp;
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
rval = qla2x00_mgmt_svr_login(ha);
|
||||||
|
if (rval)
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
|
||||||
|
/* Issue GFPN_ID */
|
||||||
|
list[i].fp_speeds = list[i].fp_speed = 0;
|
||||||
|
|
||||||
|
/* Prepare common MS IOCB */
|
||||||
|
ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE,
|
||||||
|
GPSC_RSP_SIZE);
|
||||||
|
|
||||||
|
/* Prepare CT request */
|
||||||
|
ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
|
||||||
|
GPSC_CMD, GPSC_RSP_SIZE);
|
||||||
|
ct_rsp = &ha->ct_sns->p.rsp;
|
||||||
|
|
||||||
|
/* Prepare CT arguments -- port_name */
|
||||||
|
memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
|
||||||
|
WWN_SIZE);
|
||||||
|
|
||||||
|
/* Execute MS IOCB */
|
||||||
|
rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
|
||||||
|
sizeof(ms_iocb_entry_t));
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
/*EMPTY*/
|
||||||
|
DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB "
|
||||||
|
"failed (%d).\n", ha->host_no, rval));
|
||||||
|
} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
|
||||||
|
"GPSC") != QLA_SUCCESS) {
|
||||||
|
rval = QLA_FUNCTION_FAILED;
|
||||||
|
} else {
|
||||||
|
/* Save portname */
|
||||||
|
list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds;
|
||||||
|
list[i].fp_speed = ct_rsp->rsp.gpsc.speed;
|
||||||
|
|
||||||
|
DEBUG2_3(printk("scsi(%ld): GPSC ext entry - "
|
||||||
|
"fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
|
||||||
|
"speed=%04x.\n", ha->host_no,
|
||||||
|
list[i].fabric_port_name[0],
|
||||||
|
list[i].fabric_port_name[1],
|
||||||
|
list[i].fabric_port_name[2],
|
||||||
|
list[i].fabric_port_name[3],
|
||||||
|
list[i].fabric_port_name[4],
|
||||||
|
list[i].fabric_port_name[5],
|
||||||
|
list[i].fabric_port_name[6],
|
||||||
|
list[i].fabric_port_name[7],
|
||||||
|
be16_to_cpu(list[i].fp_speeds),
|
||||||
|
be16_to_cpu(list[i].fp_speed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last device exit. */
|
||||||
|
if (list[i].d_id.b.rsvd_1 != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
|
|
@ -2074,6 +2074,19 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
|
||||||
new_fcport->flags &= ~FCF_FABRIC_DEVICE;
|
new_fcport->flags &= ~FCF_FABRIC_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Base iIDMA settings on HBA port speed. */
|
||||||
|
switch (ha->link_data_rate) {
|
||||||
|
case PORT_SPEED_1GB:
|
||||||
|
fcport->fp_speed = cpu_to_be16(BIT_15);
|
||||||
|
break;
|
||||||
|
case PORT_SPEED_2GB:
|
||||||
|
fcport->fp_speed = cpu_to_be16(BIT_14);
|
||||||
|
break;
|
||||||
|
case PORT_SPEED_4GB:
|
||||||
|
fcport->fp_speed = cpu_to_be16(BIT_13);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
qla2x00_update_fcport(ha, fcport);
|
qla2x00_update_fcport(ha, fcport);
|
||||||
|
|
||||||
found_devs++;
|
found_devs++;
|
||||||
|
@ -2109,6 +2122,62 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
|
||||||
|
{
|
||||||
|
#define LS_UNKNOWN 2
|
||||||
|
static char *link_speeds[5] = { "1", "2", "?", "4" };
|
||||||
|
int rval;
|
||||||
|
uint16_t port_speed, mb[6];
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (be16_to_cpu(fcport->fp_speed)) {
|
||||||
|
case BIT_15:
|
||||||
|
port_speed = PORT_SPEED_1GB;
|
||||||
|
break;
|
||||||
|
case BIT_14:
|
||||||
|
port_speed = PORT_SPEED_2GB;
|
||||||
|
break;
|
||||||
|
case BIT_13:
|
||||||
|
port_speed = PORT_SPEED_4GB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- "
|
||||||
|
"unsupported FM port operating speed (%04x).\n",
|
||||||
|
ha->host_no, fcport->port_name[0], fcport->port_name[1],
|
||||||
|
fcport->port_name[2], fcport->port_name[3],
|
||||||
|
fcport->port_name[4], fcport->port_name[5],
|
||||||
|
fcport->port_name[6], fcport->port_name[7],
|
||||||
|
be16_to_cpu(fcport->fp_speed)));
|
||||||
|
port_speed = PORT_SPEED_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (port_speed == PORT_SPEED_UNKNOWN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb);
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA "
|
||||||
|
"%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n",
|
||||||
|
ha->host_no, fcport->port_name[0], fcport->port_name[1],
|
||||||
|
fcport->port_name[2], fcport->port_name[3],
|
||||||
|
fcport->port_name[4], fcport->port_name[5],
|
||||||
|
fcport->port_name[6], fcport->port_name[7], rval,
|
||||||
|
port_speed, mb[0], mb[1]));
|
||||||
|
} else {
|
||||||
|
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||||
|
"iIDMA adjusted to %s GB/s on "
|
||||||
|
"%02x%02x%02x%02x%02x%02x%02x%02x.\n",
|
||||||
|
link_speeds[port_speed], fcport->port_name[0],
|
||||||
|
fcport->port_name[1], fcport->port_name[2],
|
||||||
|
fcport->port_name[3], fcport->port_name[4],
|
||||||
|
fcport->port_name[5], fcport->port_name[6],
|
||||||
|
fcport->port_name[7]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qla2x00_update_fcport
|
* qla2x00_update_fcport
|
||||||
* Updates device on list.
|
* Updates device on list.
|
||||||
|
@ -2135,6 +2204,8 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
|
||||||
PORT_RETRY_TIME);
|
PORT_RETRY_TIME);
|
||||||
fcport->flags &= ~FCF_LOGIN_NEEDED;
|
fcport->flags &= ~FCF_LOGIN_NEEDED;
|
||||||
|
|
||||||
|
qla2x00_iidma_fcport(ha, fcport);
|
||||||
|
|
||||||
atomic_set(&fcport->state, FCS_ONLINE);
|
atomic_set(&fcport->state, FCS_ONLINE);
|
||||||
|
|
||||||
if (ha->flags.init_done)
|
if (ha->flags.init_done)
|
||||||
|
@ -2416,6 +2487,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
|
||||||
} else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) {
|
} else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) {
|
||||||
kfree(swl);
|
kfree(swl);
|
||||||
swl = NULL;
|
swl = NULL;
|
||||||
|
} else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) {
|
||||||
|
qla2x00_gpsc(ha, swl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
swl_idx = 0;
|
swl_idx = 0;
|
||||||
|
@ -2450,6 +2523,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
|
||||||
swl[swl_idx].node_name, WWN_SIZE);
|
swl[swl_idx].node_name, WWN_SIZE);
|
||||||
memcpy(new_fcport->port_name,
|
memcpy(new_fcport->port_name,
|
||||||
swl[swl_idx].port_name, WWN_SIZE);
|
swl[swl_idx].port_name, WWN_SIZE);
|
||||||
|
memcpy(new_fcport->fabric_port_name,
|
||||||
|
swl[swl_idx].fabric_port_name, WWN_SIZE);
|
||||||
|
new_fcport->fp_speed = swl[swl_idx].fp_speed;
|
||||||
|
|
||||||
if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
|
if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
|
||||||
last_dev = 1;
|
last_dev = 1;
|
||||||
|
@ -2507,6 +2583,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
|
||||||
|
|
||||||
found++;
|
found++;
|
||||||
|
|
||||||
|
/* Update port state. */
|
||||||
|
memcpy(fcport->fabric_port_name,
|
||||||
|
new_fcport->fabric_port_name, WWN_SIZE);
|
||||||
|
fcport->fp_speed = new_fcport->fp_speed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If address the same and state FCS_ONLINE, nothing
|
* If address the same and state FCS_ONLINE, nothing
|
||||||
* changed.
|
* changed.
|
||||||
|
|
|
@ -400,7 +400,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
||||||
case MBA_LOOP_UP: /* Loop Up Event */
|
case MBA_LOOP_UP: /* Loop Up Event */
|
||||||
if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
||||||
link_speed = link_speeds[0];
|
link_speed = link_speeds[0];
|
||||||
ha->link_data_rate = LDR_1GB;
|
ha->link_data_rate = PORT_SPEED_1GB;
|
||||||
} else {
|
} else {
|
||||||
link_speed = link_speeds[LS_UNKNOWN];
|
link_speed = link_speeds[LS_UNKNOWN];
|
||||||
if (mb[1] < 5)
|
if (mb[1] < 5)
|
||||||
|
@ -429,7 +429,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
||||||
}
|
}
|
||||||
|
|
||||||
ha->flags.management_server_logged_in = 0;
|
ha->flags.management_server_logged_in = 0;
|
||||||
ha->link_data_rate = LDR_UNKNOWN;
|
ha->link_data_rate = PORT_SPEED_UNKNOWN;
|
||||||
if (ql2xfdmienable)
|
if (ql2xfdmienable)
|
||||||
set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
|
set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2540,3 +2540,89 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
|
||||||
|
uint16_t *port_speed, uint16_t *mb)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
mbx_cmd_t mc;
|
||||||
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha))
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||||
|
|
||||||
|
mcp->mb[0] = MBC_PORT_PARAMS;
|
||||||
|
mcp->mb[1] = loop_id;
|
||||||
|
mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0;
|
||||||
|
mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||||
|
mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
|
||||||
|
mcp->tov = 30;
|
||||||
|
mcp->flags = 0;
|
||||||
|
rval = qla2x00_mailbox_command(ha, mcp);
|
||||||
|
|
||||||
|
/* Return mailbox statuses. */
|
||||||
|
if (mb != NULL) {
|
||||||
|
mb[0] = mcp->mb[0];
|
||||||
|
mb[1] = mcp->mb[1];
|
||||||
|
mb[3] = mcp->mb[3];
|
||||||
|
mb[4] = mcp->mb[4];
|
||||||
|
mb[5] = mcp->mb[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
|
||||||
|
ha->host_no, rval));
|
||||||
|
} else {
|
||||||
|
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||||
|
if (port_speed)
|
||||||
|
*port_speed = mcp->mb[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
|
||||||
|
uint16_t port_speed, uint16_t *mb)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
mbx_cmd_t mc;
|
||||||
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
|
if (!IS_QLA24XX(ha))
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||||
|
|
||||||
|
mcp->mb[0] = MBC_PORT_PARAMS;
|
||||||
|
mcp->mb[1] = loop_id;
|
||||||
|
mcp->mb[2] = BIT_0;
|
||||||
|
mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
|
||||||
|
mcp->mb[4] = mcp->mb[5] = 0;
|
||||||
|
mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||||
|
mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
|
||||||
|
mcp->tov = 30;
|
||||||
|
mcp->flags = 0;
|
||||||
|
rval = qla2x00_mailbox_command(ha, mcp);
|
||||||
|
|
||||||
|
/* Return mailbox statuses. */
|
||||||
|
if (mb != NULL) {
|
||||||
|
mb[0] = mcp->mb[0];
|
||||||
|
mb[1] = mcp->mb[1];
|
||||||
|
mb[3] = mcp->mb[3];
|
||||||
|
mb[4] = mcp->mb[4];
|
||||||
|
mb[5] = mcp->mb[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
|
||||||
|
ha->host_no, rval));
|
||||||
|
} else {
|
||||||
|
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
|
@ -1385,7 +1385,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
ha->prev_topology = 0;
|
ha->prev_topology = 0;
|
||||||
ha->init_cb_size = sizeof(init_cb_t);
|
ha->init_cb_size = sizeof(init_cb_t);
|
||||||
ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
|
ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
|
||||||
ha->link_data_rate = LDR_UNKNOWN;
|
ha->link_data_rate = PORT_SPEED_UNKNOWN;
|
||||||
ha->optrom_size = OPTROM_SIZE_2300;
|
ha->optrom_size = OPTROM_SIZE_2300;
|
||||||
|
|
||||||
/* Assign ISP specific operations. */
|
/* Assign ISP specific operations. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue