2 * Copyright(c) 2008 Intel Corporation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 * Maintained at www.Open-FCoE.org
22 #include <asm/unaligned.h>
25 struct fc_ns_fid fid
; /* port ID object */
26 struct fc_ns_fts fts
; /* FC4-types object */
32 struct fc_ns_gid_ft gid
;
33 struct fc_ns_rn_id rn
;
39 * fill FC header fields in specified fc_frame
41 static inline void fc_fill_fc_hdr(struct fc_frame
*fp
, enum fc_rctl r_ctl
,
42 u32 did
, u32 sid
, enum fc_fh_type type
,
43 u32 f_ctl
, u32 parm_offset
)
45 struct fc_frame_header
*fh
;
47 fh
= fc_frame_header_get(fp
);
50 hton24(fh
->fh_d_id
, did
);
51 hton24(fh
->fh_s_id
, sid
);
53 hton24(fh
->fh_f_ctl
, f_ctl
);
56 fh
->fh_parm_offset
= htonl(parm_offset
);
60 * fc_ct_hdr_fill- fills ct header and reset ct payload
61 * returns pointer to ct request.
63 static inline struct fc_ct_req
*fc_ct_hdr_fill(const struct fc_frame
*fp
,
64 unsigned int op
, size_t req_size
)
69 ct_plen
= sizeof(struct fc_ct_hdr
) + req_size
;
70 ct
= fc_frame_payload_get(fp
, ct_plen
);
71 memset(ct
, 0, ct_plen
);
72 ct
->hdr
.ct_rev
= FC_CT_REV
;
73 ct
->hdr
.ct_fs_type
= FC_FST_DIR
;
74 ct
->hdr
.ct_fs_subtype
= FC_NS_SUBTYPE
;
75 ct
->hdr
.ct_cmd
= htons((u16
) op
);
80 * fc_ct_fill - Fill in a name service request frame
82 static inline int fc_ct_fill(struct fc_lport
*lport
, struct fc_frame
*fp
,
83 unsigned int op
, enum fc_rctl
*r_ctl
, u32
*did
,
84 enum fc_fh_type
*fh_type
)
90 ct
= fc_ct_hdr_fill(fp
, op
, sizeof(struct fc_ns_gid_ft
));
91 ct
->payload
.gid
.fn_fc4_type
= FC_TYPE_FCP
;
95 ct
= fc_ct_hdr_fill(fp
, op
, sizeof(struct fc_ns_rft
));
96 hton24(ct
->payload
.rft
.fid
.fp_fid
,
97 fc_host_port_id(lport
->host
));
98 ct
->payload
.rft
.fts
= lport
->fcts
;
102 ct
= fc_ct_hdr_fill(fp
, op
, sizeof(struct fc_ns_rn_id
));
103 hton24(ct
->payload
.rn
.fr_fid
.fp_fid
,
104 fc_host_port_id(lport
->host
));
105 ct
->payload
.rft
.fts
= lport
->fcts
;
106 put_unaligned_be64(lport
->wwpn
, &ct
->payload
.rn
.fr_wwn
);
110 FC_DBG("Invalid op code %x \n", op
);
113 *r_ctl
= FC_RCTL_DD_UNSOL_CTL
;
114 *did
= FC_FID_DIR_SERV
;
115 *fh_type
= FC_TYPE_CT
;
120 * fc_plogi_fill - Fill in plogi request frame
122 static inline void fc_plogi_fill(struct fc_lport
*lport
, struct fc_frame
*fp
,
125 struct fc_els_flogi
*plogi
;
126 struct fc_els_csp
*csp
;
127 struct fc_els_cssp
*cp
;
129 plogi
= fc_frame_payload_get(fp
, sizeof(*plogi
));
130 memset(plogi
, 0, sizeof(*plogi
));
131 plogi
->fl_cmd
= (u8
) op
;
132 put_unaligned_be64(lport
->wwpn
, &plogi
->fl_wwpn
);
133 put_unaligned_be64(lport
->wwnn
, &plogi
->fl_wwnn
);
135 csp
= &plogi
->fl_csp
;
136 csp
->sp_hi_ver
= 0x20;
137 csp
->sp_lo_ver
= 0x20;
138 csp
->sp_bb_cred
= htons(10); /* this gets set by gateway */
139 csp
->sp_bb_data
= htons((u16
) lport
->mfs
);
140 cp
= &plogi
->fl_cssp
[3 - 1]; /* class 3 parameters */
141 cp
->cp_class
= htons(FC_CPC_VALID
| FC_CPC_SEQ
);
142 csp
->sp_features
= htons(FC_SP_FT_CIRO
);
143 csp
->sp_tot_seq
= htons(255); /* seq. we accept */
144 csp
->sp_rel_off
= htons(0x1f);
145 csp
->sp_e_d_tov
= htonl(lport
->e_d_tov
);
147 cp
->cp_rdfs
= htons((u16
) lport
->mfs
);
148 cp
->cp_con_seq
= htons(255);
153 * fc_flogi_fill - Fill in a flogi request frame.
155 static inline void fc_flogi_fill(struct fc_lport
*lport
, struct fc_frame
*fp
)
157 struct fc_els_csp
*sp
;
158 struct fc_els_cssp
*cp
;
159 struct fc_els_flogi
*flogi
;
161 flogi
= fc_frame_payload_get(fp
, sizeof(*flogi
));
162 memset(flogi
, 0, sizeof(*flogi
));
163 flogi
->fl_cmd
= (u8
) ELS_FLOGI
;
164 put_unaligned_be64(lport
->wwpn
, &flogi
->fl_wwpn
);
165 put_unaligned_be64(lport
->wwnn
, &flogi
->fl_wwnn
);
167 sp
->sp_hi_ver
= 0x20;
168 sp
->sp_lo_ver
= 0x20;
169 sp
->sp_bb_cred
= htons(10); /* this gets set by gateway */
170 sp
->sp_bb_data
= htons((u16
) lport
->mfs
);
171 cp
= &flogi
->fl_cssp
[3 - 1]; /* class 3 parameters */
172 cp
->cp_class
= htons(FC_CPC_VALID
| FC_CPC_SEQ
);
176 * fc_logo_fill - Fill in a logo request frame.
178 static inline void fc_logo_fill(struct fc_lport
*lport
, struct fc_frame
*fp
)
180 struct fc_els_logo
*logo
;
182 logo
= fc_frame_payload_get(fp
, sizeof(*logo
));
183 memset(logo
, 0, sizeof(*logo
));
184 logo
->fl_cmd
= ELS_LOGO
;
185 hton24(logo
->fl_n_port_id
, fc_host_port_id(lport
->host
));
186 logo
->fl_n_port_wwn
= htonll(lport
->wwpn
);
190 * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
192 static inline void fc_rtv_fill(struct fc_lport
*lport
, struct fc_frame
*fp
)
194 struct fc_els_rtv
*rtv
;
196 rtv
= fc_frame_payload_get(fp
, sizeof(*rtv
));
197 memset(rtv
, 0, sizeof(*rtv
));
198 rtv
->rtv_cmd
= ELS_RTV
;
202 * fc_rec_fill - Fill in rec request frame
204 static inline void fc_rec_fill(struct fc_lport
*lport
, struct fc_frame
*fp
)
206 struct fc_els_rec
*rec
;
207 struct fc_exch
*ep
= fc_seq_exch(fr_seq(fp
));
209 rec
= fc_frame_payload_get(fp
, sizeof(*rec
));
210 memset(rec
, 0, sizeof(*rec
));
211 rec
->rec_cmd
= ELS_REC
;
212 hton24(rec
->rec_s_id
, fc_host_port_id(lport
->host
));
213 rec
->rec_ox_id
= htons(ep
->oxid
);
214 rec
->rec_rx_id
= htons(ep
->rxid
);
218 * fc_prli_fill - Fill in prli request frame
220 static inline void fc_prli_fill(struct fc_lport
*lport
, struct fc_frame
*fp
)
223 struct fc_els_prli prli
;
224 struct fc_els_spp spp
;
227 pp
= fc_frame_payload_get(fp
, sizeof(*pp
));
228 memset(pp
, 0, sizeof(*pp
));
229 pp
->prli
.prli_cmd
= ELS_PRLI
;
230 pp
->prli
.prli_spp_len
= sizeof(struct fc_els_spp
);
231 pp
->prli
.prli_len
= htons(sizeof(*pp
));
232 pp
->spp
.spp_type
= FC_TYPE_FCP
;
233 pp
->spp
.spp_flags
= FC_SPP_EST_IMG_PAIR
;
234 pp
->spp
.spp_params
= htonl(lport
->service_params
);
238 * fc_scr_fill - Fill in a scr request frame.
240 static inline void fc_scr_fill(struct fc_lport
*lport
, struct fc_frame
*fp
)
242 struct fc_els_scr
*scr
;
244 scr
= fc_frame_payload_get(fp
, sizeof(*scr
));
245 memset(scr
, 0, sizeof(*scr
));
246 scr
->scr_cmd
= ELS_SCR
;
247 scr
->scr_reg_func
= ELS_SCRF_FULL
;
251 * fc_els_fill - Fill in an ELS request frame
253 static inline int fc_els_fill(struct fc_lport
*lport
, struct fc_rport
*rport
,
254 struct fc_frame
*fp
, unsigned int op
,
255 enum fc_rctl
*r_ctl
, u32
*did
, enum fc_fh_type
*fh_type
)
259 fc_plogi_fill(lport
, fp
, ELS_PLOGI
);
260 *did
= rport
->port_id
;
264 fc_flogi_fill(lport
, fp
);
269 fc_logo_fill(lport
, fp
);
272 * if rport is valid then it
273 * is port logo, therefore
274 * set did to rport id.
277 *did
= rport
->port_id
;
281 fc_rtv_fill(lport
, fp
);
282 *did
= rport
->port_id
;
286 fc_rec_fill(lport
, fp
);
287 *did
= rport
->port_id
;
291 fc_prli_fill(lport
, fp
);
292 *did
= rport
->port_id
;
296 fc_scr_fill(lport
, fp
);
301 FC_DBG("Invalid op code %x \n", op
);
305 *r_ctl
= FC_RCTL_ELS_REQ
;
306 *fh_type
= FC_TYPE_ELS
;
309 #endif /* _FC_ENCODE_H_ */