Re: [PATCH] scsi: csiostor: add support for 32 bit port capabilities

2018-03-14 Thread Martin K. Petersen

Varun,

> 32 bit port capabilities are required to support new speeds which can
> not be supported using 16 bit port capabilities.

Applied to 4.17/scsi-queue. Thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


[PATCH] scsi: csiostor: add support for 32 bit port capabilities

2018-03-11 Thread Varun Prakash
32 bit port capabilities are required to support new
speeds which can not be supported using 16 bit
port capabilities.

Signed-off-by: Varun Prakash 
---
 drivers/scsi/csiostor/csio_attr.c  |  16 ++-
 drivers/scsi/csiostor/csio_hw.c| 275 -
 drivers/scsi/csiostor/csio_hw.h|  59 
 drivers/scsi/csiostor/csio_lnode.c |   8 ++
 drivers/scsi/csiostor/csio_mb.c|  70 ++
 drivers/scsi/csiostor/csio_mb.h|   9 +-
 6 files changed, 395 insertions(+), 42 deletions(-)

diff --git a/drivers/scsi/csiostor/csio_attr.c 
b/drivers/scsi/csiostor/csio_attr.c
index 2d1c4eb..8a00403 100644
--- a/drivers/scsi/csiostor/csio_attr.c
+++ b/drivers/scsi/csiostor/csio_attr.c
@@ -274,12 +274,24 @@ csio_get_host_speed(struct Scsi_Host *shost)
 
spin_lock_irq(>lock);
switch (hw->pport[ln->portid].link_speed) {
-   case FW_PORT_CAP_SPEED_1G:
+   case FW_PORT_CAP32_SPEED_1G:
fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
break;
-   case FW_PORT_CAP_SPEED_10G:
+   case FW_PORT_CAP32_SPEED_10G:
fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
break;
+   case FW_PORT_CAP32_SPEED_25G:
+   fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
+   break;
+   case FW_PORT_CAP32_SPEED_40G:
+   fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
+   break;
+   case FW_PORT_CAP32_SPEED_50G:
+   fc_host_speed(shost) = FC_PORTSPEED_50GBIT;
+   break;
+   case FW_PORT_CAP32_SPEED_100G:
+   fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
+   break;
default:
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index 0bd1131..96bbb82 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -1409,6 +1409,235 @@ csio_config_device_caps(struct csio_hw *hw)
return rv;
 }
 
+static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
+{
+   enum cc_fec cc_fec = 0;
+
+   if (fw_fec & FW_PORT_CAP32_FEC_RS)
+   cc_fec |= FEC_RS;
+   if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
+   cc_fec |= FEC_BASER_RS;
+
+   return cc_fec;
+}
+
+static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
+{
+   fw_port_cap32_t fw_pause = 0;
+
+   if (cc_pause & PAUSE_RX)
+   fw_pause |= FW_PORT_CAP32_FC_RX;
+   if (cc_pause & PAUSE_TX)
+   fw_pause |= FW_PORT_CAP32_FC_TX;
+
+   return fw_pause;
+}
+
+static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
+{
+   fw_port_cap32_t fw_fec = 0;
+
+   if (cc_fec & FEC_RS)
+   fw_fec |= FW_PORT_CAP32_FEC_RS;
+   if (cc_fec & FEC_BASER_RS)
+   fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
+
+   return fw_fec;
+}
+
+/**
+ * fwcap_to_fwspeed - return highest speed in Port Capabilities
+ * @acaps: advertised Port Capabilities
+ *
+ * Get the highest speed for the port from the advertised Port
+ * Capabilities.
+ */
+fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps)
+{
+   #define TEST_SPEED_RETURN(__caps_speed) \
+   do { \
+   if (acaps & FW_PORT_CAP32_SPEED_##__caps_speed) \
+   return FW_PORT_CAP32_SPEED_##__caps_speed; \
+   } while (0)
+
+   TEST_SPEED_RETURN(400G);
+   TEST_SPEED_RETURN(200G);
+   TEST_SPEED_RETURN(100G);
+   TEST_SPEED_RETURN(50G);
+   TEST_SPEED_RETURN(40G);
+   TEST_SPEED_RETURN(25G);
+   TEST_SPEED_RETURN(10G);
+   TEST_SPEED_RETURN(1G);
+   TEST_SPEED_RETURN(100M);
+
+   #undef TEST_SPEED_RETURN
+
+   return 0;
+}
+
+/**
+ *  fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
+ *  @caps16: a 16-bit Port Capabilities value
+ *
+ *  Returns the equivalent 32-bit Port Capabilities value.
+ */
+fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
+{
+   fw_port_cap32_t caps32 = 0;
+
+   #define CAP16_TO_CAP32(__cap) \
+   do { \
+   if (caps16 & FW_PORT_CAP_##__cap) \
+   caps32 |= FW_PORT_CAP32_##__cap; \
+   } while (0)
+
+   CAP16_TO_CAP32(SPEED_100M);
+   CAP16_TO_CAP32(SPEED_1G);
+   CAP16_TO_CAP32(SPEED_25G);
+   CAP16_TO_CAP32(SPEED_10G);
+   CAP16_TO_CAP32(SPEED_40G);
+   CAP16_TO_CAP32(SPEED_100G);
+   CAP16_TO_CAP32(FC_RX);
+   CAP16_TO_CAP32(FC_TX);
+   CAP16_TO_CAP32(ANEG);
+   CAP16_TO_CAP32(MDIX);
+   CAP16_TO_CAP32(MDIAUTO);
+   CAP16_TO_CAP32(FEC_RS);
+   CAP16_TO_CAP32(FEC_BASER_RS);
+   CAP16_TO_CAP32(802_3_PAUSE);
+   CAP16_TO_CAP32(802_3_ASM_DIR);
+
+   #undef CAP16_TO_CAP32
+
+   return caps32;
+}
+
+/**
+ *  lstatus_to_fwcap - translate old