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>
This commit is contained in:
Varun Prakash
2018-03-11 18:02:13 +05:30
committed by Martin K. Petersen
parent 1929e82e37
commit e1735d9a98
6 changed files with 395 additions and 42 deletions

View File

@@ -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);
hw->pport[port_id].link_speed =
FW_PORT_CMD_LSPEED_G(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_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;