[LPORT_ST_RSNN_NN] =  "RSNN_NN",
        [LPORT_ST_RSPN_ID] =  "RSPN_ID",
        [LPORT_ST_RFT_ID] =   "RFT_ID",
+       [LPORT_ST_RFF_ID] =   "RFF_ID",
        [LPORT_ST_SCR] =      "SCR",
        [LPORT_ST_READY] =    "Ready",
        [LPORT_ST_LOGO] =     "LOGO",
                        case LPORT_ST_RSNN_NN:
                        case LPORT_ST_RSPN_ID:
                        case LPORT_ST_RFT_ID:
+                       case LPORT_ST_RFF_ID:
                        case LPORT_ST_SCR:
                        case LPORT_ST_DNS:
                        case LPORT_ST_FLOGI:
 
        mutex_lock(&lport->lp_mutex);
 
-       if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFT_ID) {
+       if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
                FC_LPORT_DBG(lport, "Received a name server response, "
                             "but in state %s\n", fc_lport_state(lport));
                if (IS_ERR(fp))
                        fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
                        break;
                case LPORT_ST_RFT_ID:
+                       fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
+                       break;
+               case LPORT_ST_RFF_ID:
                        fc_lport_enter_scr(lport);
                        break;
                default:
                cmd = FC_NS_RFT_ID;
                size += sizeof(struct fc_ns_rft);
                break;
+       case LPORT_ST_RFF_ID:
+               cmd = FC_NS_RFF_ID;
+               size += sizeof(struct fc_ns_rff_id);
+               break;
        default:
                fc_lport_error(lport, NULL);
                return;
        case LPORT_ST_RSNN_NN:
        case LPORT_ST_RSPN_ID:
        case LPORT_ST_RFT_ID:
+       case LPORT_ST_RFF_ID:
                fc_lport_enter_ns(lport, lport->state);
                break;
        case LPORT_ST_SCR:
 
        __u8            srr_resvd2[3];  /* reserved */
 };
 
+/*
+ * Feature bits in name server FC-4 Features object.
+ */
+#define        FCP_FEAT_TARG   (1 << 0)        /* target function supported */
+#define        FCP_FEAT_INIT   (1 << 1)        /* initiator function supported */
+
 #endif /* _FC_FCP_H_ */
 
        FC_NS_GID_FT =  0x0171,         /* get IDs by FC4 type */
        FC_NS_GPN_FT =  0x0172,         /* get port names by FC4 type */
        FC_NS_GID_PT =  0x01a1,         /* get IDs by port type */
-       FC_NS_RFT_ID =  0x0217,         /* reg FC4 type for ID */
        FC_NS_RPN_ID =  0x0212,         /* reg port name for ID */
        FC_NS_RNN_ID =  0x0213,         /* reg node name for ID */
+       FC_NS_RFT_ID =  0x0217,         /* reg FC4 type for ID */
        FC_NS_RSPN_ID = 0x0218,         /* reg symbolic port name */
+       FC_NS_RFF_ID =  0x021f,         /* reg FC4 Features for ID */
        FC_NS_RSNN_NN = 0x0239,         /* reg symbolic node name */
 };
 
        char            fr_name[];
 } __attribute__((__packed__));
 
+/*
+ * RFF_ID request - register FC-4 Features for ID.
+ */
+struct fc_ns_rff_id {
+       struct fc_ns_fid fr_fid;        /* port ID object */
+       __u8            fr_resvd[2];
+       __u8            fr_feat;        /* FC-4 Feature bits */
+       __u8            fr_type;        /* FC-4 type */
+} __attribute__((__packed__));
+
 #endif /* _FC_NS_H_ */
 
                struct fc_ns_gid_ft gid;
                struct fc_ns_rn_id  rn;
                struct fc_ns_rft rft;
+               struct fc_ns_rff_id rff;
                struct fc_ns_fid fid;
                struct fc_ns_rsnn snn;
                struct fc_ns_rspn spn;
                ct->payload.rft.fts = lport->fcts;
                break;
 
+       case FC_NS_RFF_ID:
+               ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id));
+               hton24(ct->payload.rff.fr_fid.fp_fid,
+                      fc_host_port_id(lport->host));
+               ct->payload.rff.fr_type = FC_TYPE_FCP;
+               if (lport->service_params & FCP_SPPF_INIT_FCN)
+                       ct->payload.rff.fr_feat = FCP_FEAT_INIT;
+               if (lport->service_params & FCP_SPPF_TARG_FCN)
+                       ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
+               break;
+
        case FC_NS_RNN_ID:
                ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
                hton24(ct->payload.rn.fr_fid.fp_fid,
 
  * @LPORT_ST_DNS:      Waiting for name server remote port to become ready
  * @LPORT_ST_RPN_ID:   Register port name by ID (RPN_ID) sent
  * @LPORT_ST_RFT_ID:   Register Fibre Channel types by ID (RFT_ID) sent
+ * @LPORT_ST_RFF_ID:   Register FC-4 Features by ID (RFF_ID) sent
  * @LPORT_ST_SCR:      State Change Register (SCR) sent
  * @LPORT_ST_READY:    Ready for use
  * @LPORT_ST_LOGO:     Local port logout (LOGO) sent
        LPORT_ST_RSNN_NN,
        LPORT_ST_RSPN_ID,
        LPORT_ST_RFT_ID,
+       LPORT_ST_RFF_ID,
        LPORT_ST_SCR,
        LPORT_ST_READY,
        LPORT_ST_LOGO,