} else if (port_type == FW_PORT_TYPE_SFP ||
                   port_type == FW_PORT_TYPE_QSFP_10G ||
                   port_type == FW_PORT_TYPE_QSA ||
-                  port_type == FW_PORT_TYPE_QSFP) {
+                  port_type == FW_PORT_TYPE_QSFP ||
+                  port_type == FW_PORT_TYPE_CR4_QSFP ||
+                  port_type == FW_PORT_TYPE_CR_QSFP ||
+                  port_type == FW_PORT_TYPE_CR2_QSFP ||
+                  port_type == FW_PORT_TYPE_SFP28) {
                if (mod_type == FW_PORT_MOD_TYPE_LR ||
                    mod_type == FW_PORT_MOD_TYPE_SR ||
                    mod_type == FW_PORT_MOD_TYPE_ER ||
                        return PORT_DA;
                else
                        return PORT_OTHER;
+       } else if (port_type == FW_PORT_TYPE_KR4_100G ||
+                  port_type == FW_PORT_TYPE_KR_SFP28) {
+               return PORT_NONE;
        }
 
        return PORT_OTHER;
        case FW_PORT_TYPE_CR_QSFP:
        case FW_PORT_TYPE_SFP28:
                SET_LMM(FIBRE);
-               SET_LMM(25000baseCR_Full);
+               FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
+               FW_CAPS_TO_LMM(SPEED_10G, 10000baseT_Full);
+               FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
+               break;
+
+       case FW_PORT_TYPE_KR_SFP28:
+               SET_LMM(Backplane);
+               FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
+               FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
+               FW_CAPS_TO_LMM(SPEED_25G, 25000baseKR_Full);
+               break;
+
+       case FW_PORT_TYPE_CR2_QSFP:
+               SET_LMM(FIBRE);
+               SET_LMM(50000baseSR2_Full);
                break;
 
        case FW_PORT_TYPE_KR4_100G:
 static int get_link_ksettings(struct net_device *dev,
                              struct ethtool_link_ksettings *link_ksettings)
 {
-       const struct port_info *pi = netdev_priv(dev);
+       struct port_info *pi = netdev_priv(dev);
        struct ethtool_link_settings *base = &link_ksettings->base;
 
        ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
        ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
        ethtool_link_ksettings_zero_link_mode(link_ksettings, lp_advertising);
 
+       /* For the nonce, the Firmware doesn't send up Port State changes
+        * when the Virtual Interface attached to the Port is down.  So
+        * if it's down, let's grab any changes.
+        */
+       if (!netif_running(dev))
+               (void)t4_update_port_info(pi);
+
        base->port = from_fw_port_mod_type(pi->port_type, pi->mod_type);
 
        if (pi->mdio_addr >= 0) {
 
                lc->fc = fc;
                lc->supported = be16_to_cpu(p->u.info.pcap);
                lc->lp_advertising = be16_to_cpu(p->u.info.lpacap);
+
                t4_os_link_changed(adap, pi->port_id, link_ok);
        }
 }
 
+/**
+ *     t4_update_port_info - retrieve and update port information if changed
+ *     @pi: the port_info
+ *
+ *     We issue a Get Port Information Command to the Firmware and, if
+ *     successful, we check to see if anything is different from what we
+ *     last recorded and update things accordingly.
+ */
+int t4_update_port_info(struct port_info *pi)
+{
+       struct fw_port_cmd port_cmd;
+       int ret;
+
+       memset(&port_cmd, 0, sizeof(port_cmd));
+       port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
+                                           FW_CMD_REQUEST_F | FW_CMD_READ_F |
+                                           FW_PORT_CMD_PORTID_V(pi->port_id));
+       port_cmd.action_to_len16 = cpu_to_be32(
+               FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
+               FW_LEN16(port_cmd));
+       ret = t4_wr_mbox(pi->adapter, pi->adapter->mbox,
+                        &port_cmd, sizeof(port_cmd), &port_cmd);
+       if (ret)
+               return ret;
+
+       t4_handle_get_port_info(pi, (__be64 *)&port_cmd);
+       return 0;
+}
+
 /**
  *      t4_handle_fw_rpl - process a FW reply message
  *      @adap: the adapter