scsi: qla2xxx: Add Serdes support for ISP28XX
authorJoe Carnuccio <joe.carnuccio@cavium.com>
Tue, 12 Mar 2019 18:08:14 +0000 (11:08 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 19 Mar 2019 16:22:54 +0000 (12:22 -0400)
This patch adds sysfs node for serdes_version and also cleans up port_speed
display.

Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c

index f035251..93da79a 100644 (file)
@@ -1378,6 +1378,21 @@ qla24xx_84xx_fw_version_show(struct device *dev,
 }
 
 static ssize_t
+qla2x00_serdes_version_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;
+
+       if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
+               return scnprintf(buf, PAGE_SIZE, "\n");
+
+       return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
+           ha->serdes_version[0], ha->serdes_version[1],
+           ha->serdes_version[2]);
+}
+
+static ssize_t
 qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
     char *buf)
 {
@@ -2220,6 +2235,7 @@ static DEVICE_ATTR(84xx_fw_version, S_IRUGO, qla24xx_84xx_fw_version_show,
                   NULL);
 static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
                   NULL);
+static DEVICE_ATTR(serdes_version, 0444, qla2x00_serdes_version_show, NULL);
 static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
 static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
 static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
@@ -2272,6 +2288,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
        &dev_attr_optrom_fw_version,
        &dev_attr_84xx_fw_version,
        &dev_attr_total_isp_aborts,
+       &dev_attr_serdes_version,
        &dev_attr_mpi_version,
        &dev_attr_phy_version,
        &dev_attr_flash_block_size,
@@ -2328,16 +2345,15 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost)
 static void
 qla2x00_get_host_speed(struct Scsi_Host *shost)
 {
-       struct qla_hw_data *ha = ((struct scsi_qla_host *)
-                                       (shost_priv(shost)))->hw;
-       u32 speed = FC_PORTSPEED_UNKNOWN;
+       scsi_qla_host_t *vha = shost_priv(shost);
+       u32 speed;
 
-       if (IS_QLAFX00(ha)) {
+       if (IS_QLAFX00(vha->hw)) {
                qlafx00_get_host_speed(shost);
                return;
        }
 
-       switch (ha->link_data_rate) {
+       switch (vha->hw->link_data_rate) {
        case PORT_SPEED_1GB:
                speed = FC_PORTSPEED_1GBIT;
                break;
@@ -2362,7 +2378,11 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
        case PORT_SPEED_64GB:
                speed = FC_PORTSPEED_64GBIT;
                break;
+       default:
+               speed = FC_PORTSPEED_UNKNOWN;
+               break;
        }
+
        fc_host_speed(shost) = speed;
 }
 
@@ -2370,7 +2390,7 @@ static void
 qla2x00_get_host_port_type(struct Scsi_Host *shost)
 {
        scsi_qla_host_t *vha = shost_priv(shost);
-       uint32_t port_type = FC_PORTTYPE_UNKNOWN;
+       uint32_t port_type;
 
        if (vha->vp_idx) {
                fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
@@ -2389,7 +2409,11 @@ qla2x00_get_host_port_type(struct Scsi_Host *shost)
        case ISP_CFG_F:
                port_type = FC_PORTTYPE_NPORT;
                break;
+       default:
+               port_type = FC_PORTTYPE_UNKNOWN;
+               break;
        }
+
        fc_host_port_type(shost) = port_type;
 }
 
@@ -2451,13 +2475,10 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
        fc_starget_port_id(starget) = port_id;
 }
 
-static void
+static inline void
 qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
 {
-       if (timeout)
-               rport->dev_loss_tmo = timeout;
-       else
-               rport->dev_loss_tmo = 1;
+       rport->dev_loss_tmo = timeout ? timeout : 1;
 }
 
 static void
index c64cd55..a466130 100644 (file)
@@ -4023,6 +4023,7 @@ struct qla_hw_data {
        uint8_t         fw_seriallink_options[4];
        uint16_t        fw_seriallink_options24[4];
 
+       uint8_t         serdes_version[3];
        uint8_t         mpi_version[3];
        uint32_t        mpi_capabilities;
        uint8_t         phy_version[3];
@@ -4034,7 +4035,8 @@ struct qla_hw_data {
        /* Firmware dump information. */
        struct qla2xxx_fw_dump *fw_dump;
        uint32_t        fw_dump_len;
-       int             fw_dumped;
+       bool            fw_dumped;
+       bool            fw_dump_mpi;
        unsigned long   fw_dump_cap_flags;
 #define RISC_PAUSE_CMPL                0
 #define DMA_SHUTDOWN_CMPL      1
index 41b5fa1..2d96344 100644 (file)
@@ -2783,6 +2783,31 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
        return &p->p.req;
 }
 
+static uint16_t
+qla2x00_port_speed_capability(uint16_t speed)
+{
+       switch (speed) {
+       case BIT_15:
+               return PORT_SPEED_1GB;
+       case BIT_14:
+               return PORT_SPEED_2GB;
+       case BIT_13:
+               return PORT_SPEED_4GB;
+       case BIT_12:
+               return PORT_SPEED_10GB;
+       case BIT_11:
+               return PORT_SPEED_8GB;
+       case BIT_10:
+               return PORT_SPEED_16GB;
+       case BIT_8:
+               return PORT_SPEED_32GB;
+       case BIT_7:
+               return PORT_SPEED_64GB;
+       default:
+               return PORT_SPEED_UNKNOWN;
+       }
+}
+
 /**
  * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
  * @vha: HA context
@@ -2855,31 +2880,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
                        }
                        rval = QLA_FUNCTION_FAILED;
                } else {
-                       /* Save port-speed */
-                       switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
-                       case BIT_15:
-                               list[i].fp_speed = PORT_SPEED_1GB;
-                               break;
-                       case BIT_14:
-                               list[i].fp_speed = PORT_SPEED_2GB;
-                               break;
-                       case BIT_13:
-                               list[i].fp_speed = PORT_SPEED_4GB;
-                               break;
-                       case BIT_12:
-                               list[i].fp_speed = PORT_SPEED_10GB;
-                               break;
-                       case BIT_11:
-                               list[i].fp_speed = PORT_SPEED_8GB;
-                               break;
-                       case BIT_10:
-                               list[i].fp_speed = PORT_SPEED_16GB;
-                               break;
-                       case BIT_8:
-                               list[i].fp_speed = PORT_SPEED_32GB;
-                               break;
-                       }
-
+                       list->fp_speed = qla2x00_port_speed_capability(
+                           be16_to_cpu(ct_rsp->rsp.gpsc.speed));
                        ql_dbg(ql_dbg_disc, vha, 0x205b,
                            "GPSC ext entry - fpn "
                            "%8phN speeds=%04x speed=%04x.\n",
@@ -3048,29 +3050,8 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
                        goto done;
                }
        } else {
-               switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
-               case BIT_15:
-                       fcport->fp_speed = PORT_SPEED_1GB;
-                       break;
-               case BIT_14:
-                       fcport->fp_speed = PORT_SPEED_2GB;
-                       break;
-               case BIT_13:
-                       fcport->fp_speed = PORT_SPEED_4GB;
-                       break;
-               case BIT_12:
-                       fcport->fp_speed = PORT_SPEED_10GB;
-                       break;
-               case BIT_11:
-                       fcport->fp_speed = PORT_SPEED_8GB;
-                       break;
-               case BIT_10:
-                       fcport->fp_speed = PORT_SPEED_16GB;
-                       break;
-               case BIT_8:
-                       fcport->fp_speed = PORT_SPEED_32GB;
-                       break;
-               }
+               fcport->fp_speed = qla2x00_port_speed_capability(
+                   be16_to_cpu(ct_rsp->rsp.gpsc.speed));
 
                ql_dbg(ql_dbg_disc, vha, 0x2054,
                    "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
index 1552f81..c6139c0 100644 (file)
@@ -714,7 +714,9 @@ skip_rio:
                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);
-
+               ha->fw_dump_mpi =
+                   (IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&
+                   RD_REG_WORD(&reg24->mailbox7) & BIT_8;
                ha->isp_ops->fw_dump(vha, 1);
                ha->flags.fw_init_done = 0;
                QLA_FW_STOPPED(ha);
index 3812211..304c214 100644 (file)
@@ -634,14 +634,15 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
                mcp->out_mb |= MBX_4;
        }
 
-       mcp->in_mb = MBX_0;
+       mcp->in_mb = MBX_1|MBX_0;
        mcp->tov = MBX_TOV_SECONDS;
        mcp->flags = 0;
        rval = qla2x00_mailbox_command(vha, mcp);
 
        if (rval != QLA_SUCCESS) {
                ql_dbg(ql_dbg_mbx, vha, 0x1023,
-                   "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+                   "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, 0x1024,
                    "Done %s.\n", __func__);
@@ -1057,7 +1058,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
        if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
                mcp->in_mb |=
                    MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
-                   MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8;
+                   MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7;
 
        mcp->flags = 0;
        mcp->tov = MBX_TOV_SECONDS;
@@ -1124,6 +1125,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
        }
 
        if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
+               ha->serdes_version[0] = mcp->mb[7] & 0xff;
+               ha->serdes_version[1] = mcp->mb[8] >> 8;
+               ha->serdes_version[2] = mcp->mb[8] & 0xff;
                ha->mpi_version[0] = mcp->mb[10] & 0xff;
                ha->mpi_version[1] = mcp->mb[11] >> 8;
                ha->mpi_version[2] = mcp->mb[11] & 0xff;
@@ -3748,7 +3752,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
        rval = qla2x00_mailbox_command(vha, mcp);
 
        /* Return mailbox statuses. */
-       if (mb != NULL) {
+       if (mb) {
                mb[0] = mcp->mb[0];
                mb[1] = mcp->mb[1];
                mb[3] = mcp->mb[3];
@@ -3783,7 +3787,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
        mcp->mb[0] = MBC_PORT_PARAMS;
        mcp->mb[1] = loop_id;
        mcp->mb[2] = BIT_0;
-       mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
+       mcp->mb[3] = port_speed & 0x3F;
        mcp->mb[9] = vha->vp_idx;
        mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
        mcp->in_mb = MBX_3|MBX_1|MBX_0;
@@ -3792,7 +3796,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
        rval = qla2x00_mailbox_command(vha, mcp);
 
        /* Return mailbox statuses. */
-       if (mb != NULL) {
+       if (mb) {
                mb[0] = mcp->mb[0];
                mb[1] = mcp->mb[1];
                mb[3] = mcp->mb[3];
@@ -4823,10 +4827,10 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
        if (rval != QLA_SUCCESS) {
                ql_dbg(ql_dbg_mbx, vha, 0x10e9,
                    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
-               if (mcp->mb[0] == MBS_COMMAND_ERROR &&
-                   mcp->mb[1] == 0x22)
+               if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) {
                        /* sfp is not there */
                        rval = QLA_INTERFACE_ERROR;
+               }
        } else {
                ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
                    "Done %s.\n", __func__);
@@ -5166,13 +5170,14 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
        mcp->mb[3] = MSW(data);
        mcp->mb[8] = MSW(risc_addr);
        mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
-       mcp->in_mb = MBX_0;
+       mcp->in_mb = MBX_1|MBX_0;
        mcp->tov = 30;
        mcp->flags = 0;
        rval = qla2x00_mailbox_command(vha, mcp);
        if (rval != QLA_SUCCESS) {
                ql_dbg(ql_dbg_mbx, vha, 0x1101,
-                   "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+                   "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, 0x1102,
                    "Done %s.\n", __func__);