OSDN Git Service

scsi: csiostor: fix incorrect port capabilities
authorVarun Prakash <varun@chelsio.com>
Sat, 11 Aug 2018 15:44:08 +0000 (21:14 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Oct 2018 06:55:51 +0000 (08:55 +0200)
[ Upstream commit 68bdc630721c40e908d22cffe07b5ca225a69f6e ]

 - use be32_to_cpu() instead of ntohs() for 32 bit port capabilities.

 - add a new function fwcaps32_to_caps16() to convert 32 bit port
   capabilities to 16 bit port capabilities.

Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/csiostor/csio_hw.c
drivers/scsi/csiostor/csio_hw.h
drivers/scsi/csiostor/csio_mb.c

index 1ee255a..e4baf04 100644 (file)
@@ -1513,6 +1513,46 @@ fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
 }
 
 /**
+ *     fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
+ *     @caps32: a 32-bit Port Capabilities value
+ *
+ *     Returns the equivalent 16-bit Port Capabilities value.  Note that
+ *     not all 32-bit Port Capabilities can be represented in the 16-bit
+ *     Port Capabilities and some fields/values may not make it.
+ */
+fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
+{
+       fw_port_cap16_t caps16 = 0;
+
+       #define CAP32_TO_CAP16(__cap) \
+               do { \
+                       if (caps32 & FW_PORT_CAP32_##__cap) \
+                               caps16 |= FW_PORT_CAP_##__cap; \
+               } while (0)
+
+       CAP32_TO_CAP16(SPEED_100M);
+       CAP32_TO_CAP16(SPEED_1G);
+       CAP32_TO_CAP16(SPEED_10G);
+       CAP32_TO_CAP16(SPEED_25G);
+       CAP32_TO_CAP16(SPEED_40G);
+       CAP32_TO_CAP16(SPEED_100G);
+       CAP32_TO_CAP16(FC_RX);
+       CAP32_TO_CAP16(FC_TX);
+       CAP32_TO_CAP16(802_3_PAUSE);
+       CAP32_TO_CAP16(802_3_ASM_DIR);
+       CAP32_TO_CAP16(ANEG);
+       CAP32_TO_CAP16(FORCE_PAUSE);
+       CAP32_TO_CAP16(MDIAUTO);
+       CAP32_TO_CAP16(MDISTRAIGHT);
+       CAP32_TO_CAP16(FEC_RS);
+       CAP32_TO_CAP16(FEC_BASER_RS);
+
+       #undef CAP32_TO_CAP16
+
+       return caps16;
+}
+
+/**
  *      lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities
  *      @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value
  *
@@ -1670,7 +1710,7 @@ csio_enable_ports(struct csio_hw *hw)
                        val = 1;
 
                        csio_mb_params(hw, mbp, CSIO_MB_DEFAULT_TMO,
-                                      hw->pfn, 0, 1, &param, &val, false,
+                                      hw->pfn, 0, 1, &param, &val, true,
                                       NULL);
 
                        if (csio_mb_issue(hw, mbp)) {
@@ -1680,16 +1720,9 @@ csio_enable_ports(struct csio_hw *hw)
                                return -EINVAL;
                        }
 
-                       csio_mb_process_read_params_rsp(hw, mbp, &retval, 1,
-                                                       &val);
-                       if (retval != FW_SUCCESS) {
-                               csio_err(hw, "FW_PARAMS_CMD(r) port:%d failed: 0x%x\n",
-                                        portid, retval);
-                               mempool_free(mbp, hw->mb_mempool);
-                               return -EINVAL;
-                       }
-
-                       fw_caps = val;
+                       csio_mb_process_read_params_rsp(hw, mbp, &retval,
+                                                       0, NULL);
+                       fw_caps = retval ? FW_CAPS16 : FW_CAPS32;
                }
 
                /* Read PORT information */
index 9e73ef7..e351af6 100644 (file)
@@ -639,6 +639,7 @@ int csio_handle_intr_status(struct csio_hw *, unsigned int,
 
 fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps);
 fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16);
+fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32);
 fw_port_cap32_t lstatus_to_fwcap(u32 lstatus);
 
 int csio_hw_start(struct csio_hw *);
index c026417..6f13673 100644 (file)
@@ -368,7 +368,7 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
                        FW_CMD_LEN16_V(sizeof(*cmdp) / 16));
 
        if (fw_caps == FW_CAPS16)
-               cmdp->u.l1cfg.rcap = cpu_to_be32(fc);
+               cmdp->u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(fc));
        else
                cmdp->u.l1cfg32.rcap32 = cpu_to_be32(fc);
 }
@@ -395,8 +395,8 @@ csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp,
                        *pcaps = fwcaps16_to_caps32(ntohs(rsp->u.info.pcap));
                        *acaps = fwcaps16_to_caps32(ntohs(rsp->u.info.acap));
                } else {
-                       *pcaps = ntohs(rsp->u.info32.pcaps32);
-                       *acaps = ntohs(rsp->u.info32.acaps32);
+                       *pcaps = be32_to_cpu(rsp->u.info32.pcaps32);
+                       *acaps = be32_to_cpu(rsp->u.info32.acaps32);
                }
        }
 }