diff options
author | Varun Prakash <varun@chelsio.com> | 2018-03-11 18:02:13 +0530 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-03-15 00:41:51 -0400 |
commit | e1735d9a98ab5593484bbba1933e362a261e0de0 (patch) | |
tree | 88304d7f300edfbc0444ba5d9495c94413781a8c /drivers/scsi/csiostor/csio_mb.c | |
parent | 1929e82e37d9c43ce7063025877a779ac649d1e0 (diff) | |
download | lwn-e1735d9a98ab5593484bbba1933e362a261e0de0.tar.gz lwn-e1735d9a98ab5593484bbba1933e362a261e0de0.zip |
scsi: csiostor: add support for 32 bit port capabilities
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 <varun@chelsio.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/csiostor/csio_mb.c')
-rw-r--r-- | drivers/scsi/csiostor/csio_mb.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index 5f4e0a787bd1..c026417269c3 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c @@ -326,10 +326,6 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET); } -#define CSIO_ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ - FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G |\ - FW_PORT_CAP_ANEG) - /* * csio_mb_port- FW PORT command helper * @hw: The HW structure @@ -344,11 +340,10 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, */ void csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, - uint8_t portid, bool wr, uint32_t fc, uint16_t caps, + u8 portid, bool wr, uint32_t fc, uint16_t fw_caps, void (*cbfn) (struct csio_hw *, struct csio_mb *)) { struct fw_port_cmd *cmdp = (struct fw_port_cmd *)(mbp->mb); - unsigned int lfc = 0, mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO); CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); @@ -358,26 +353,24 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, FW_PORT_CMD_PORTID_V(portid)); if (!wr) { cmdp->action_to_len16 = htonl( - FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | + FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16 + ? FW_PORT_ACTION_GET_PORT_INFO + : FW_PORT_ACTION_GET_PORT_INFO32) | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); return; } /* Set port */ cmdp->action_to_len16 = htonl( - FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) | + FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16 + ? FW_PORT_ACTION_L1_CFG + : FW_PORT_ACTION_L1_CFG32) | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); - if (fc & PAUSE_RX) - lfc |= FW_PORT_CAP_FC_RX; - if (fc & PAUSE_TX) - lfc |= FW_PORT_CAP_FC_TX; - - if (!(caps & FW_PORT_CAP_ANEG)) - cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) | lfc); + if (fw_caps == FW_CAPS16) + cmdp->u.l1cfg.rcap = cpu_to_be32(fc); else - cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) | - lfc | mdi); + cmdp->u.l1cfg32.rcap32 = cpu_to_be32(fc); } /* @@ -390,14 +383,22 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, */ void csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp, - enum fw_retval *retval, uint16_t *caps) + enum fw_retval *retval, uint16_t fw_caps, + u32 *pcaps, u32 *acaps) { struct fw_port_cmd *rsp = (struct fw_port_cmd *)(mbp->mb); *retval = FW_CMD_RETVAL_G(ntohl(rsp->action_to_len16)); - if (*retval == FW_SUCCESS) - *caps = ntohs(rsp->u.info.pcap); + if (*retval == FW_SUCCESS) { + if (fw_caps == FW_CAPS16) { + *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); + } + } } /* @@ -1409,6 +1410,7 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd) uint32_t link_status; uint16_t action; uint8_t mod_type; + fw_port_cap32_t linkattr; if (opcode == FW_PORT_CMD) { pcmd = (struct fw_port_cmd *)cmd; @@ -1416,22 +1418,34 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd) ntohl(pcmd->op_to_portid)); action = FW_PORT_CMD_ACTION_G( ntohl(pcmd->action_to_len16)); - if (action != FW_PORT_ACTION_GET_PORT_INFO) { + if (action != FW_PORT_ACTION_GET_PORT_INFO && + action != FW_PORT_ACTION_GET_PORT_INFO32) { csio_err(hw, "Unhandled FW_PORT_CMD action: %u\n", action); return -EINVAL; } - link_status = ntohl(pcmd->u.info.lstatus_to_modtype); - mod_type = FW_PORT_CMD_MODTYPE_G(link_status); + if (action == FW_PORT_ACTION_GET_PORT_INFO) { + link_status = ntohl(pcmd->u.info.lstatus_to_modtype); + mod_type = FW_PORT_CMD_MODTYPE_G(link_status); + linkattr = lstatus_to_fwcap(link_status); + + hw->pport[port_id].link_status = + FW_PORT_CMD_LSTATUS_G(link_status); + } else { + link_status = + ntohl(pcmd->u.info32.lstatus32_to_cbllen32); + mod_type = FW_PORT_CMD_MODTYPE32_G(link_status); + linkattr = ntohl(pcmd->u.info32.linkattr32); + + hw->pport[port_id].link_status = + FW_PORT_CMD_LSTATUS32_G(link_status); + } - hw->pport[port_id].link_status = - FW_PORT_CMD_LSTATUS_G(link_status); - hw->pport[port_id].link_speed = - FW_PORT_CMD_LSPEED_G(link_status); + hw->pport[port_id].link_speed = fwcap_to_fwspeed(linkattr); csio_info(hw, "Port:%x - LINK %s\n", port_id, - FW_PORT_CMD_LSTATUS_G(link_status) ? "UP" : "DOWN"); + hw->pport[port_id].link_status ? "UP" : "DOWN"); if (mod_type != hw->pport[port_id].mod_type) { hw->pport[port_id].mod_type = mod_type; |