1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright(c) 2007 Intel Corporation. All rights reserved.
4 *
5 * Maintained at www.Open-FCoE.org
6 */
7
8 /*
9 * PORT LOCKING NOTES
10 *
11 * These comments only apply to the 'port code' which consists of the lport,
12 * disc and rport blocks.
13 *
14 * MOTIVATION
15 *
16 * The lport, disc and rport blocks all have mutexes that are used to protect
17 * those objects. The main motivation for these locks is to prevent from
18 * having an lport reset just before we send a frame. In that scenario the
19 * lport's FID would get set to zero and then we'd send a frame with an
20 * invalid SID. We also need to ensure that states don't change unexpectedly
21 * while processing another state.
22 *
23 * HIERARCHY
24 *
25 * The following hierarchy defines the locking rules. A greater lock
26 * may be held before acquiring a lesser lock, but a lesser lock should never
27 * be held while attempting to acquire a greater lock. Here is the hierarchy-
28 *
29 * lport > disc, lport > rport, disc > rport
30 *
31 * CALLBACKS
32 *
33 * The callbacks cause complications with this scheme. There is a callback
34 * from the rport (to either lport or disc) and a callback from disc
35 * (to the lport).
36 *
37 * As rports exit the rport state machine a callback is made to the owner of
38 * the rport to notify success or failure. Since the callback is likely to
39 * cause the lport or disc to grab its lock we cannot hold the rport lock
40 * while making the callback. To ensure that the rport is not free'd while
41 * processing the callback the rport callbacks are serialized through a
42 * single-threaded workqueue. An rport would never be free'd while in a
43 * callback handler because no other rport work in this queue can be executed
44 * at the same time.
45 *
46 * When discovery succeeds or fails a callback is made to the lport as
47 * notification. Currently, successful discovery causes the lport to take no
48 * action. A failure will cause the lport to reset. There is likely a circular
49 * locking problem with this implementation.
50 */
51
52 /*
53 * LPORT LOCKING
54 *
55 * The critical sections protected by the lport's mutex are quite broad and
56 * may be improved upon in the future. The lport code and its locking doesn't
57 * influence the I/O path, so excessive locking doesn't penalize I/O
58 * performance.
59 *
60 * The strategy is to lock whenever processing a request or response. Note
61 * that every _enter_* function corresponds to a state change. They generally
62 * change the lports state and then send a request out on the wire. We lock
63 * before calling any of these functions to protect that state change. This
64 * means that the entry points into the lport block manage the locks while
65 * the state machine can transition between states (i.e. _enter_* functions)
66 * while always staying protected.
67 *
68 * When handling responses we also hold the lport mutex broadly. When the
69 * lport receives the response frame it locks the mutex and then calls the
70 * appropriate handler for the particuar response. Generally a response will
71 * trigger a state change and so the lock must already be held.
72 *
73 * Retries also have to consider the locking. The retries occur from a work
74 * context and the work function will lock the lport and then retry the state
75 * (i.e. _enter_* function).
76 */
77
78 #include <linux/timer.h>
79 #include <linux/delay.h>
80 #include <linux/module.h>
81 #include <linux/slab.h>
82 #include <asm/unaligned.h>
83
84 #include <scsi/fc/fc_gs.h>
85
86 #include <scsi/libfc.h>
87 #include <scsi/fc_encode.h>
88 #include <linux/scatterlist.h>
89
90 #include "fc_libfc.h"
91
92 /* Fabric IDs to use for point-to-point mode, chosen on whims. */
93 #define FC_LOCAL_PTP_FID_LO 0x010101
94 #define FC_LOCAL_PTP_FID_HI 0x010102
95
96 #define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/
97
98 static void fc_lport_error(struct fc_lport *, struct fc_frame *);
99
100 static void fc_lport_enter_reset(struct fc_lport *);
101 static void fc_lport_enter_flogi(struct fc_lport *);
102 static void fc_lport_enter_dns(struct fc_lport *);
103 static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
104 static void fc_lport_enter_scr(struct fc_lport *);
105 static void fc_lport_enter_ready(struct fc_lport *);
106 static void fc_lport_enter_logo(struct fc_lport *);
107 static void fc_lport_enter_fdmi(struct fc_lport *lport);
108 static void fc_lport_enter_ms(struct fc_lport *, enum fc_lport_state);
109
110 static const char *fc_lport_state_names[] = {
111 [LPORT_ST_DISABLED] = "disabled",
112 [LPORT_ST_FLOGI] = "FLOGI",
113 [LPORT_ST_DNS] = "dNS",
114 [LPORT_ST_RNN_ID] = "RNN_ID",
115 [LPORT_ST_RSNN_NN] = "RSNN_NN",
116 [LPORT_ST_RSPN_ID] = "RSPN_ID",
117 [LPORT_ST_RFT_ID] = "RFT_ID",
118 [LPORT_ST_RFF_ID] = "RFF_ID",
119 [LPORT_ST_FDMI] = "FDMI",
120 [LPORT_ST_RHBA] = "RHBA",
121 [LPORT_ST_RPA] = "RPA",
122 [LPORT_ST_DHBA] = "DHBA",
123 [LPORT_ST_DPRT] = "DPRT",
124 [LPORT_ST_SCR] = "SCR",
125 [LPORT_ST_READY] = "Ready",
126 [LPORT_ST_LOGO] = "LOGO",
127 [LPORT_ST_RESET] = "reset",
128 };
129
130 /**
131 * struct fc_bsg_info - FC Passthrough managemet structure
132 * @job: The passthrough job
133 * @lport: The local port to pass through a command
134 * @rsp_code: The expected response code
135 * @sg: job->reply_payload.sg_list
136 * @nents: job->reply_payload.sg_cnt
137 * @offset: The offset into the response data
138 */
139 struct fc_bsg_info {
140 struct bsg_job *job;
141 struct fc_lport *lport;
142 u16 rsp_code;
143 struct scatterlist *sg;
144 u32 nents;
145 size_t offset;
146 };
147
148 /**
149 * fc_frame_drop() - Dummy frame handler
150 * @lport: The local port the frame was received on
151 * @fp: The received frame
152 */
fc_frame_drop(struct fc_lport * lport,struct fc_frame * fp)153 static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
154 {
155 fc_frame_free(fp);
156 return 0;
157 }
158
159 /**
160 * fc_lport_rport_callback() - Event handler for rport events
161 * @lport: The lport which is receiving the event
162 * @rdata: private remote port data
163 * @event: The event that occurred
164 *
165 * Locking Note: The rport lock should not be held when calling
166 * this function.
167 */
fc_lport_rport_callback(struct fc_lport * lport,struct fc_rport_priv * rdata,enum fc_rport_event event)168 static void fc_lport_rport_callback(struct fc_lport *lport,
169 struct fc_rport_priv *rdata,
170 enum fc_rport_event event)
171 {
172 FC_LPORT_DBG(lport, "Received a %d event for port (%6.6x)\n", event,
173 rdata->ids.port_id);
174
175 mutex_lock(&lport->lp_mutex);
176 switch (event) {
177 case RPORT_EV_READY:
178 if (lport->state == LPORT_ST_DNS) {
179 lport->dns_rdata = rdata;
180 fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
181 } else if (lport->state == LPORT_ST_FDMI) {
182 lport->ms_rdata = rdata;
183 fc_lport_enter_ms(lport, LPORT_ST_DHBA);
184 } else {
185 FC_LPORT_DBG(lport, "Received an READY event "
186 "on port (%6.6x) for the directory "
187 "server, but the lport is not "
188 "in the DNS or FDMI state, it's in the "
189 "%d state", rdata->ids.port_id,
190 lport->state);
191 fc_rport_logoff(rdata);
192 }
193 break;
194 case RPORT_EV_LOGO:
195 case RPORT_EV_FAILED:
196 case RPORT_EV_STOP:
197 if (rdata->ids.port_id == FC_FID_DIR_SERV)
198 lport->dns_rdata = NULL;
199 else if (rdata->ids.port_id == FC_FID_MGMT_SERV)
200 lport->ms_rdata = NULL;
201 break;
202 case RPORT_EV_NONE:
203 break;
204 }
205 mutex_unlock(&lport->lp_mutex);
206 }
207
208 /**
209 * fc_lport_state() - Return a string which represents the lport's state
210 * @lport: The lport whose state is to converted to a string
211 */
fc_lport_state(struct fc_lport * lport)212 static const char *fc_lport_state(struct fc_lport *lport)
213 {
214 const char *cp;
215
216 cp = fc_lport_state_names[lport->state];
217 if (!cp)
218 cp = "unknown";
219 return cp;
220 }
221
222 /**
223 * fc_lport_ptp_setup() - Create an rport for point-to-point mode
224 * @lport: The lport to attach the ptp rport to
225 * @remote_fid: The FID of the ptp rport
226 * @remote_wwpn: The WWPN of the ptp rport
227 * @remote_wwnn: The WWNN of the ptp rport
228 */
fc_lport_ptp_setup(struct fc_lport * lport,u32 remote_fid,u64 remote_wwpn,u64 remote_wwnn)229 static void fc_lport_ptp_setup(struct fc_lport *lport,
230 u32 remote_fid, u64 remote_wwpn,
231 u64 remote_wwnn)
232 {
233 lockdep_assert_held(&lport->lp_mutex);
234
235 if (lport->ptp_rdata) {
236 fc_rport_logoff(lport->ptp_rdata);
237 kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
238 }
239 mutex_lock(&lport->disc.disc_mutex);
240 lport->ptp_rdata = fc_rport_create(lport, remote_fid);
241 if (!lport->ptp_rdata) {
242 printk(KERN_WARNING "libfc: Failed to setup lport 0x%x\n",
243 lport->port_id);
244 mutex_unlock(&lport->disc.disc_mutex);
245 return;
246 }
247 kref_get(&lport->ptp_rdata->kref);
248 lport->ptp_rdata->ids.port_name = remote_wwpn;
249 lport->ptp_rdata->ids.node_name = remote_wwnn;
250 mutex_unlock(&lport->disc.disc_mutex);
251
252 fc_rport_login(lport->ptp_rdata);
253
254 fc_lport_enter_ready(lport);
255 }
256
257 /**
258 * fc_get_host_port_state() - Return the port state of the given Scsi_Host
259 * @shost: The SCSI host whose port state is to be determined
260 */
fc_get_host_port_state(struct Scsi_Host * shost)261 void fc_get_host_port_state(struct Scsi_Host *shost)
262 {
263 struct fc_lport *lport = shost_priv(shost);
264
265 mutex_lock(&lport->lp_mutex);
266 if (!lport->link_up)
267 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
268 else
269 switch (lport->state) {
270 case LPORT_ST_READY:
271 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
272 break;
273 default:
274 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
275 }
276 mutex_unlock(&lport->lp_mutex);
277 }
278 EXPORT_SYMBOL(fc_get_host_port_state);
279
280 /**
281 * fc_get_host_speed() - Return the speed of the given Scsi_Host
282 * @shost: The SCSI host whose port speed is to be determined
283 */
fc_get_host_speed(struct Scsi_Host * shost)284 void fc_get_host_speed(struct Scsi_Host *shost)
285 {
286 struct fc_lport *lport = shost_priv(shost);
287
288 fc_host_speed(shost) = lport->link_speed;
289 }
290 EXPORT_SYMBOL(fc_get_host_speed);
291
292 /**
293 * fc_get_host_stats() - Return the Scsi_Host's statistics
294 * @shost: The SCSI host whose statistics are to be returned
295 */
fc_get_host_stats(struct Scsi_Host * shost)296 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
297 {
298 struct fc_host_statistics *fc_stats;
299 struct fc_lport *lport = shost_priv(shost);
300 unsigned int cpu;
301 u64 fcp_in_bytes = 0;
302 u64 fcp_out_bytes = 0;
303
304 fc_stats = &lport->host_stats;
305 memset(fc_stats, 0, sizeof(struct fc_host_statistics));
306
307 fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
308
309 for_each_possible_cpu(cpu) {
310 struct fc_stats *stats;
311
312 stats = per_cpu_ptr(lport->stats, cpu);
313
314 fc_stats->tx_frames += stats->TxFrames;
315 fc_stats->tx_words += stats->TxWords;
316 fc_stats->rx_frames += stats->RxFrames;
317 fc_stats->rx_words += stats->RxWords;
318 fc_stats->error_frames += stats->ErrorFrames;
319 fc_stats->invalid_crc_count += stats->InvalidCRCCount;
320 fc_stats->fcp_input_requests += stats->InputRequests;
321 fc_stats->fcp_output_requests += stats->OutputRequests;
322 fc_stats->fcp_control_requests += stats->ControlRequests;
323 fcp_in_bytes += stats->InputBytes;
324 fcp_out_bytes += stats->OutputBytes;
325 fc_stats->fcp_packet_alloc_failures += stats->FcpPktAllocFails;
326 fc_stats->fcp_packet_aborts += stats->FcpPktAborts;
327 fc_stats->fcp_frame_alloc_failures += stats->FcpFrameAllocFails;
328 fc_stats->link_failure_count += stats->LinkFailureCount;
329 }
330 fc_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000);
331 fc_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000);
332 fc_stats->lip_count = -1;
333 fc_stats->nos_count = -1;
334 fc_stats->loss_of_sync_count = -1;
335 fc_stats->loss_of_signal_count = -1;
336 fc_stats->prim_seq_protocol_err_count = -1;
337 fc_stats->dumped_frames = -1;
338
339 /* update exches stats */
340 fc_exch_update_stats(lport);
341
342 return fc_stats;
343 }
344 EXPORT_SYMBOL(fc_get_host_stats);
345
346 /**
347 * fc_lport_flogi_fill() - Fill in FLOGI command for request
348 * @lport: The local port the FLOGI is for
349 * @flogi: The FLOGI command
350 * @op: The opcode
351 */
fc_lport_flogi_fill(struct fc_lport * lport,struct fc_els_flogi * flogi,unsigned int op)352 static void fc_lport_flogi_fill(struct fc_lport *lport,
353 struct fc_els_flogi *flogi,
354 unsigned int op)
355 {
356 struct fc_els_csp *sp;
357 struct fc_els_cssp *cp;
358
359 memset(flogi, 0, sizeof(*flogi));
360 flogi->fl_cmd = (u8) op;
361 put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
362 put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
363 sp = &flogi->fl_csp;
364 sp->sp_hi_ver = 0x20;
365 sp->sp_lo_ver = 0x20;
366 sp->sp_bb_cred = htons(10); /* this gets set by gateway */
367 sp->sp_bb_data = htons((u16) lport->mfs);
368 cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
369 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
370 if (op != ELS_FLOGI) {
371 sp->sp_features = htons(FC_SP_FT_CIRO);
372 sp->sp_tot_seq = htons(255); /* seq. we accept */
373 sp->sp_rel_off = htons(0x1f);
374 sp->sp_e_d_tov = htonl(lport->e_d_tov);
375
376 cp->cp_rdfs = htons((u16) lport->mfs);
377 cp->cp_con_seq = htons(255);
378 cp->cp_open_seq = 1;
379 }
380 }
381
382 /**
383 * fc_lport_add_fc4_type() - Add a supported FC-4 type to a local port
384 * @lport: The local port to add a new FC-4 type to
385 * @type: The new FC-4 type
386 */
fc_lport_add_fc4_type(struct fc_lport * lport,enum fc_fh_type type)387 static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
388 {
389 __be32 *mp;
390
391 mp = &lport->fcts.ff_type_map[type / FC_NS_BPW];
392 *mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW));
393 }
394
395 /**
396 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
397 * @lport: Fibre Channel local port receiving the RLIR
398 * @fp: The RLIR request frame
399 */
fc_lport_recv_rlir_req(struct fc_lport * lport,struct fc_frame * fp)400 static void fc_lport_recv_rlir_req(struct fc_lport *lport, struct fc_frame *fp)
401 {
402 lockdep_assert_held(&lport->lp_mutex);
403
404 FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
405 fc_lport_state(lport));
406
407 fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
408 fc_frame_free(fp);
409 }
410
411 /**
412 * fc_lport_recv_echo_req() - Handle received ECHO request
413 * @lport: The local port receiving the ECHO
414 * @in_fp: ECHO request frame
415 */
fc_lport_recv_echo_req(struct fc_lport * lport,struct fc_frame * in_fp)416 static void fc_lport_recv_echo_req(struct fc_lport *lport,
417 struct fc_frame *in_fp)
418 {
419 struct fc_frame *fp;
420 unsigned int len;
421 void *pp;
422 void *dp;
423
424 lockdep_assert_held(&lport->lp_mutex);
425
426 FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
427 fc_lport_state(lport));
428
429 len = fr_len(in_fp) - sizeof(struct fc_frame_header);
430 pp = fc_frame_payload_get(in_fp, len);
431
432 if (len < sizeof(__be32))
433 len = sizeof(__be32);
434
435 fp = fc_frame_alloc(lport, len);
436 if (fp) {
437 dp = fc_frame_payload_get(fp, len);
438 memcpy(dp, pp, len);
439 *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
440 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
441 lport->tt.frame_send(lport, fp);
442 }
443 fc_frame_free(in_fp);
444 }
445
446 /**
447 * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
448 * @lport: The local port receiving the RNID
449 * @in_fp: The RNID request frame
450 */
fc_lport_recv_rnid_req(struct fc_lport * lport,struct fc_frame * in_fp)451 static void fc_lport_recv_rnid_req(struct fc_lport *lport,
452 struct fc_frame *in_fp)
453 {
454 struct fc_frame *fp;
455 struct fc_els_rnid *req;
456 struct {
457 struct fc_els_rnid_resp rnid;
458 struct fc_els_rnid_cid cid;
459 struct fc_els_rnid_gen gen;
460 } *rp;
461 struct fc_seq_els_data rjt_data;
462 u8 fmt;
463 size_t len;
464
465 lockdep_assert_held(&lport->lp_mutex);
466
467 FC_LPORT_DBG(lport, "Received RNID request while in state %s\n",
468 fc_lport_state(lport));
469
470 req = fc_frame_payload_get(in_fp, sizeof(*req));
471 if (!req) {
472 rjt_data.reason = ELS_RJT_LOGIC;
473 rjt_data.explan = ELS_EXPL_NONE;
474 fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
475 } else {
476 fmt = req->rnid_fmt;
477 len = sizeof(*rp);
478 if (fmt != ELS_RNIDF_GEN ||
479 ntohl(lport->rnid_gen.rnid_atype) == 0) {
480 fmt = ELS_RNIDF_NONE; /* nothing to provide */
481 len -= sizeof(rp->gen);
482 }
483 fp = fc_frame_alloc(lport, len);
484 if (fp) {
485 rp = fc_frame_payload_get(fp, len);
486 memset(rp, 0, len);
487 rp->rnid.rnid_cmd = ELS_LS_ACC;
488 rp->rnid.rnid_fmt = fmt;
489 rp->rnid.rnid_cid_len = sizeof(rp->cid);
490 rp->cid.rnid_wwpn = htonll(lport->wwpn);
491 rp->cid.rnid_wwnn = htonll(lport->wwnn);
492 if (fmt == ELS_RNIDF_GEN) {
493 rp->rnid.rnid_sid_len = sizeof(rp->gen);
494 memcpy(&rp->gen, &lport->rnid_gen,
495 sizeof(rp->gen));
496 }
497 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
498 lport->tt.frame_send(lport, fp);
499 }
500 }
501 fc_frame_free(in_fp);
502 }
503
504 /**
505 * fc_lport_recv_logo_req() - Handle received fabric LOGO request
506 * @lport: The local port receiving the LOGO
507 * @fp: The LOGO request frame
508 */
fc_lport_recv_logo_req(struct fc_lport * lport,struct fc_frame * fp)509 static void fc_lport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
510 {
511 lockdep_assert_held(&lport->lp_mutex);
512
513 fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
514 fc_lport_enter_reset(lport);
515 fc_frame_free(fp);
516 }
517
518 /**
519 * fc_fabric_login() - Start the lport state machine
520 * @lport: The local port that should log into the fabric
521 *
522 * Locking Note: This function should not be called
523 * with the lport lock held.
524 */
fc_fabric_login(struct fc_lport * lport)525 int fc_fabric_login(struct fc_lport *lport)
526 {
527 int rc = -1;
528
529 mutex_lock(&lport->lp_mutex);
530 if (lport->state == LPORT_ST_DISABLED ||
531 lport->state == LPORT_ST_LOGO) {
532 fc_lport_state_enter(lport, LPORT_ST_RESET);
533 fc_lport_enter_reset(lport);
534 rc = 0;
535 }
536 mutex_unlock(&lport->lp_mutex);
537
538 return rc;
539 }
540 EXPORT_SYMBOL(fc_fabric_login);
541
542 /**
543 * __fc_linkup() - Handler for transport linkup events
544 * @lport: The lport whose link is up
545 */
__fc_linkup(struct fc_lport * lport)546 void __fc_linkup(struct fc_lport *lport)
547 {
548 lockdep_assert_held(&lport->lp_mutex);
549
550 if (!lport->link_up) {
551 lport->link_up = 1;
552
553 if (lport->state == LPORT_ST_RESET)
554 fc_lport_enter_flogi(lport);
555 }
556 }
557
558 /**
559 * fc_linkup() - Handler for transport linkup events
560 * @lport: The local port whose link is up
561 */
fc_linkup(struct fc_lport * lport)562 void fc_linkup(struct fc_lport *lport)
563 {
564 printk(KERN_INFO "host%d: libfc: Link up on port (%6.6x)\n",
565 lport->host->host_no, lport->port_id);
566
567 mutex_lock(&lport->lp_mutex);
568 __fc_linkup(lport);
569 mutex_unlock(&lport->lp_mutex);
570 }
571 EXPORT_SYMBOL(fc_linkup);
572
573 /**
574 * __fc_linkdown() - Handler for transport linkdown events
575 * @lport: The lport whose link is down
576 */
__fc_linkdown(struct fc_lport * lport)577 void __fc_linkdown(struct fc_lport *lport)
578 {
579 lockdep_assert_held(&lport->lp_mutex);
580
581 if (lport->link_up) {
582 lport->link_up = 0;
583 fc_lport_enter_reset(lport);
584 lport->tt.fcp_cleanup(lport);
585 }
586 }
587
588 /**
589 * fc_linkdown() - Handler for transport linkdown events
590 * @lport: The local port whose link is down
591 */
fc_linkdown(struct fc_lport * lport)592 void fc_linkdown(struct fc_lport *lport)
593 {
594 printk(KERN_INFO "host%d: libfc: Link down on port (%6.6x)\n",
595 lport->host->host_no, lport->port_id);
596
597 mutex_lock(&lport->lp_mutex);
598 __fc_linkdown(lport);
599 mutex_unlock(&lport->lp_mutex);
600 }
601 EXPORT_SYMBOL(fc_linkdown);
602
603 /**
604 * fc_fabric_logoff() - Logout of the fabric
605 * @lport: The local port to logoff the fabric
606 *
607 * Return value:
608 * 0 for success, -1 for failure
609 */
fc_fabric_logoff(struct fc_lport * lport)610 int fc_fabric_logoff(struct fc_lport *lport)
611 {
612 lport->tt.disc_stop_final(lport);
613 mutex_lock(&lport->lp_mutex);
614 if (lport->dns_rdata)
615 fc_rport_logoff(lport->dns_rdata);
616 mutex_unlock(&lport->lp_mutex);
617 fc_rport_flush_queue();
618 mutex_lock(&lport->lp_mutex);
619 fc_lport_enter_logo(lport);
620 mutex_unlock(&lport->lp_mutex);
621 cancel_delayed_work_sync(&lport->retry_work);
622 return 0;
623 }
624 EXPORT_SYMBOL(fc_fabric_logoff);
625
626 /**
627 * fc_lport_destroy() - Unregister a fc_lport
628 * @lport: The local port to unregister
629 *
630 * Note:
631 * exit routine for fc_lport instance
632 * clean-up all the allocated memory
633 * and free up other system resources.
634 *
635 */
fc_lport_destroy(struct fc_lport * lport)636 int fc_lport_destroy(struct fc_lport *lport)
637 {
638 mutex_lock(&lport->lp_mutex);
639 lport->state = LPORT_ST_DISABLED;
640 lport->link_up = 0;
641 lport->tt.frame_send = fc_frame_drop;
642 mutex_unlock(&lport->lp_mutex);
643
644 lport->tt.fcp_abort_io(lport);
645 lport->tt.disc_stop_final(lport);
646 lport->tt.exch_mgr_reset(lport, 0, 0);
647 cancel_delayed_work_sync(&lport->retry_work);
648 fc_fc4_del_lport(lport);
649 return 0;
650 }
651 EXPORT_SYMBOL(fc_lport_destroy);
652
653 /**
654 * fc_set_mfs() - Set the maximum frame size for a local port
655 * @lport: The local port to set the MFS for
656 * @mfs: The new MFS
657 */
fc_set_mfs(struct fc_lport * lport,u32 mfs)658 int fc_set_mfs(struct fc_lport *lport, u32 mfs)
659 {
660 unsigned int old_mfs;
661 int rc = -EINVAL;
662
663 mutex_lock(&lport->lp_mutex);
664
665 old_mfs = lport->mfs;
666
667 if (mfs >= FC_MIN_MAX_FRAME) {
668 mfs &= ~3;
669 if (mfs > FC_MAX_FRAME)
670 mfs = FC_MAX_FRAME;
671 mfs -= sizeof(struct fc_frame_header);
672 lport->mfs = mfs;
673 rc = 0;
674 }
675
676 if (!rc && mfs < old_mfs)
677 fc_lport_enter_reset(lport);
678
679 mutex_unlock(&lport->lp_mutex);
680
681 return rc;
682 }
683 EXPORT_SYMBOL(fc_set_mfs);
684
685 /**
686 * fc_lport_disc_callback() - Callback for discovery events
687 * @lport: The local port receiving the event
688 * @event: The discovery event
689 */
fc_lport_disc_callback(struct fc_lport * lport,enum fc_disc_event event)690 static void fc_lport_disc_callback(struct fc_lport *lport,
691 enum fc_disc_event event)
692 {
693 switch (event) {
694 case DISC_EV_SUCCESS:
695 FC_LPORT_DBG(lport, "Discovery succeeded\n");
696 break;
697 case DISC_EV_FAILED:
698 printk(KERN_ERR "host%d: libfc: "
699 "Discovery failed for port (%6.6x)\n",
700 lport->host->host_no, lport->port_id);
701 mutex_lock(&lport->lp_mutex);
702 fc_lport_enter_reset(lport);
703 mutex_unlock(&lport->lp_mutex);
704 break;
705 case DISC_EV_NONE:
706 WARN_ON(1);
707 break;
708 }
709 }
710
711 /**
712 * fc_rport_enter_ready() - Enter the ready state and start discovery
713 * @lport: The local port that is ready
714 */
fc_lport_enter_ready(struct fc_lport * lport)715 static void fc_lport_enter_ready(struct fc_lport *lport)
716 {
717 lockdep_assert_held(&lport->lp_mutex);
718
719 FC_LPORT_DBG(lport, "Entered READY from state %s\n",
720 fc_lport_state(lport));
721
722 fc_lport_state_enter(lport, LPORT_ST_READY);
723 if (lport->vport)
724 fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
725 fc_vports_linkchange(lport);
726
727 if (!lport->ptp_rdata)
728 lport->tt.disc_start(fc_lport_disc_callback, lport);
729 }
730
731 /**
732 * fc_lport_set_port_id() - set the local port Port ID
733 * @lport: The local port which will have its Port ID set.
734 * @port_id: The new port ID.
735 * @fp: The frame containing the incoming request, or NULL.
736 */
fc_lport_set_port_id(struct fc_lport * lport,u32 port_id,struct fc_frame * fp)737 static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
738 struct fc_frame *fp)
739 {
740 lockdep_assert_held(&lport->lp_mutex);
741
742 if (port_id)
743 printk(KERN_INFO "host%d: Assigned Port ID %6.6x\n",
744 lport->host->host_no, port_id);
745
746 lport->port_id = port_id;
747
748 /* Update the fc_host */
749 fc_host_port_id(lport->host) = port_id;
750
751 if (lport->tt.lport_set_port_id)
752 lport->tt.lport_set_port_id(lport, port_id, fp);
753 }
754
755 /**
756 * fc_lport_set_port_id() - set the local port Port ID for point-to-multipoint
757 * @lport: The local port which will have its Port ID set.
758 * @port_id: The new port ID.
759 *
760 * Called by the lower-level driver when transport sets the local port_id.
761 * This is used in VN_port to VN_port mode for FCoE, and causes FLOGI and
762 * discovery to be skipped.
763 */
fc_lport_set_local_id(struct fc_lport * lport,u32 port_id)764 void fc_lport_set_local_id(struct fc_lport *lport, u32 port_id)
765 {
766 mutex_lock(&lport->lp_mutex);
767
768 fc_lport_set_port_id(lport, port_id, NULL);
769
770 switch (lport->state) {
771 case LPORT_ST_RESET:
772 case LPORT_ST_FLOGI:
773 if (port_id)
774 fc_lport_enter_ready(lport);
775 break;
776 default:
777 break;
778 }
779 mutex_unlock(&lport->lp_mutex);
780 }
781 EXPORT_SYMBOL(fc_lport_set_local_id);
782
783 /**
784 * fc_lport_recv_flogi_req() - Receive a FLOGI request
785 * @lport: The local port that received the request
786 * @rx_fp: The FLOGI frame
787 *
788 * A received FLOGI request indicates a point-to-point connection.
789 * Accept it with the common service parameters indicating our N port.
790 * Set up to do a PLOGI if we have the higher-number WWPN.
791 */
fc_lport_recv_flogi_req(struct fc_lport * lport,struct fc_frame * rx_fp)792 static void fc_lport_recv_flogi_req(struct fc_lport *lport,
793 struct fc_frame *rx_fp)
794 {
795 struct fc_frame *fp;
796 struct fc_frame_header *fh;
797 struct fc_els_flogi *flp;
798 struct fc_els_flogi *new_flp;
799 u64 remote_wwpn;
800 u32 remote_fid;
801 u32 local_fid;
802
803 lockdep_assert_held(&lport->lp_mutex);
804
805 FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n",
806 fc_lport_state(lport));
807
808 remote_fid = fc_frame_sid(rx_fp);
809 flp = fc_frame_payload_get(rx_fp, sizeof(*flp));
810 if (!flp)
811 goto out;
812 remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
813 if (remote_wwpn == lport->wwpn) {
814 printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
815 "with same WWPN %16.16llx\n",
816 lport->host->host_no, remote_wwpn);
817 goto out;
818 }
819 FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn);
820
821 /*
822 * XXX what is the right thing to do for FIDs?
823 * The originator might expect our S_ID to be 0xfffffe.
824 * But if so, both of us could end up with the same FID.
825 */
826 local_fid = FC_LOCAL_PTP_FID_LO;
827 if (remote_wwpn < lport->wwpn) {
828 local_fid = FC_LOCAL_PTP_FID_HI;
829 if (!remote_fid || remote_fid == local_fid)
830 remote_fid = FC_LOCAL_PTP_FID_LO;
831 } else if (!remote_fid) {
832 remote_fid = FC_LOCAL_PTP_FID_HI;
833 }
834
835 fc_lport_set_port_id(lport, local_fid, rx_fp);
836
837 fp = fc_frame_alloc(lport, sizeof(*flp));
838 if (fp) {
839 new_flp = fc_frame_payload_get(fp, sizeof(*flp));
840 fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI);
841 new_flp->fl_cmd = (u8) ELS_LS_ACC;
842
843 /*
844 * Send the response. If this fails, the originator should
845 * repeat the sequence.
846 */
847 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
848 fh = fc_frame_header_get(fp);
849 hton24(fh->fh_s_id, local_fid);
850 hton24(fh->fh_d_id, remote_fid);
851 lport->tt.frame_send(lport, fp);
852
853 } else {
854 fc_lport_error(lport, fp);
855 }
856 fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
857 get_unaligned_be64(&flp->fl_wwnn));
858 out:
859 fc_frame_free(rx_fp);
860 }
861
862 /**
863 * fc_lport_recv_els_req() - The generic lport ELS request handler
864 * @lport: The local port that received the request
865 * @fp: The request frame
866 *
867 * This function will see if the lport handles the request or
868 * if an rport should handle the request.
869 *
870 * Locking Note: This function should not be called with the lport
871 * lock held because it will grab the lock.
872 */
fc_lport_recv_els_req(struct fc_lport * lport,struct fc_frame * fp)873 static void fc_lport_recv_els_req(struct fc_lport *lport,
874 struct fc_frame *fp)
875 {
876 mutex_lock(&lport->lp_mutex);
877
878 /*
879 * Handle special ELS cases like FLOGI, LOGO, and
880 * RSCN here. These don't require a session.
881 * Even if we had a session, it might not be ready.
882 */
883 if (!lport->link_up)
884 fc_frame_free(fp);
885 else {
886 /*
887 * Check opcode.
888 */
889 switch (fc_frame_payload_op(fp)) {
890 case ELS_FLOGI:
891 if (!lport->point_to_multipoint)
892 fc_lport_recv_flogi_req(lport, fp);
893 else
894 fc_rport_recv_req(lport, fp);
895 break;
896 case ELS_LOGO:
897 if (fc_frame_sid(fp) == FC_FID_FLOGI)
898 fc_lport_recv_logo_req(lport, fp);
899 else
900 fc_rport_recv_req(lport, fp);
901 break;
902 case ELS_RSCN:
903 lport->tt.disc_recv_req(lport, fp);
904 break;
905 case ELS_ECHO:
906 fc_lport_recv_echo_req(lport, fp);
907 break;
908 case ELS_RLIR:
909 fc_lport_recv_rlir_req(lport, fp);
910 break;
911 case ELS_RNID:
912 fc_lport_recv_rnid_req(lport, fp);
913 break;
914 default:
915 fc_rport_recv_req(lport, fp);
916 break;
917 }
918 }
919 mutex_unlock(&lport->lp_mutex);
920 }
921
fc_lport_els_prli(struct fc_rport_priv * rdata,u32 spp_len,const struct fc_els_spp * spp_in,struct fc_els_spp * spp_out)922 static int fc_lport_els_prli(struct fc_rport_priv *rdata, u32 spp_len,
923 const struct fc_els_spp *spp_in,
924 struct fc_els_spp *spp_out)
925 {
926 return FC_SPP_RESP_INVL;
927 }
928
929 struct fc4_prov fc_lport_els_prov = {
930 .prli = fc_lport_els_prli,
931 .recv = fc_lport_recv_els_req,
932 };
933
934 /**
935 * fc_lport_recv() - The generic lport request handler
936 * @lport: The lport that received the request
937 * @fp: The frame the request is in
938 *
939 * Locking Note: This function should not be called with the lport
940 * lock held because it may grab the lock.
941 */
fc_lport_recv(struct fc_lport * lport,struct fc_frame * fp)942 void fc_lport_recv(struct fc_lport *lport, struct fc_frame *fp)
943 {
944 struct fc_frame_header *fh = fc_frame_header_get(fp);
945 struct fc_seq *sp = fr_seq(fp);
946 struct fc4_prov *prov;
947
948 /*
949 * Use RCU read lock and module_lock to be sure module doesn't
950 * deregister and get unloaded while we're calling it.
951 * try_module_get() is inlined and accepts a NULL parameter.
952 * Only ELSes and FCP target ops should come through here.
953 * The locking is unfortunate, and a better scheme is being sought.
954 */
955
956 rcu_read_lock();
957 if (fh->fh_type >= FC_FC4_PROV_SIZE)
958 goto drop;
959 prov = rcu_dereference(fc_passive_prov[fh->fh_type]);
960 if (!prov || !try_module_get(prov->module))
961 goto drop;
962 rcu_read_unlock();
963 prov->recv(lport, fp);
964 module_put(prov->module);
965 return;
966 drop:
967 rcu_read_unlock();
968 FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type);
969 fc_frame_free(fp);
970 if (sp)
971 fc_exch_done(sp);
972 }
973 EXPORT_SYMBOL(fc_lport_recv);
974
975 /**
976 * fc_lport_reset() - Reset a local port
977 * @lport: The local port which should be reset
978 *
979 * Locking Note: This functions should not be called with the
980 * lport lock held.
981 */
fc_lport_reset(struct fc_lport * lport)982 int fc_lport_reset(struct fc_lport *lport)
983 {
984 cancel_delayed_work_sync(&lport->retry_work);
985 mutex_lock(&lport->lp_mutex);
986 fc_lport_enter_reset(lport);
987 mutex_unlock(&lport->lp_mutex);
988 return 0;
989 }
990 EXPORT_SYMBOL(fc_lport_reset);
991
992 /**
993 * fc_lport_reset_locked() - Reset the local port w/ the lport lock held
994 * @lport: The local port to be reset
995 */
fc_lport_reset_locked(struct fc_lport * lport)996 static void fc_lport_reset_locked(struct fc_lport *lport)
997 {
998 lockdep_assert_held(&lport->lp_mutex);
999
1000 if (lport->dns_rdata) {
1001 fc_rport_logoff(lport->dns_rdata);
1002 lport->dns_rdata = NULL;
1003 }
1004
1005 if (lport->ptp_rdata) {
1006 fc_rport_logoff(lport->ptp_rdata);
1007 kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
1008 lport->ptp_rdata = NULL;
1009 }
1010
1011 lport->tt.disc_stop(lport);
1012
1013 lport->tt.exch_mgr_reset(lport, 0, 0);
1014 fc_host_fabric_name(lport->host) = 0;
1015
1016 if (lport->port_id && (!lport->point_to_multipoint || !lport->link_up))
1017 fc_lport_set_port_id(lport, 0, NULL);
1018 }
1019
1020 /**
1021 * fc_lport_enter_reset() - Reset the local port
1022 * @lport: The local port to be reset
1023 */
fc_lport_enter_reset(struct fc_lport * lport)1024 static void fc_lport_enter_reset(struct fc_lport *lport)
1025 {
1026 lockdep_assert_held(&lport->lp_mutex);
1027
1028 FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
1029 fc_lport_state(lport));
1030
1031 if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
1032 return;
1033
1034 if (lport->vport) {
1035 if (lport->link_up)
1036 fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
1037 else
1038 fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
1039 }
1040 fc_lport_state_enter(lport, LPORT_ST_RESET);
1041 fc_host_post_event(lport->host, fc_get_event_number(),
1042 FCH_EVT_LIPRESET, 0);
1043 fc_vports_linkchange(lport);
1044 fc_lport_reset_locked(lport);
1045 if (lport->link_up)
1046 fc_lport_enter_flogi(lport);
1047 }
1048
1049 /**
1050 * fc_lport_enter_disabled() - Disable the local port
1051 * @lport: The local port to be reset
1052 */
fc_lport_enter_disabled(struct fc_lport * lport)1053 static void fc_lport_enter_disabled(struct fc_lport *lport)
1054 {
1055 lockdep_assert_held(&lport->lp_mutex);
1056
1057 FC_LPORT_DBG(lport, "Entered disabled state from %s state\n",
1058 fc_lport_state(lport));
1059
1060 fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1061 fc_vports_linkchange(lport);
1062 fc_lport_reset_locked(lport);
1063 }
1064
1065 /**
1066 * fc_lport_error() - Handler for any errors
1067 * @lport: The local port that the error was on
1068 * @fp: The error code encoded in a frame pointer
1069 *
1070 * If the error was caused by a resource allocation failure
1071 * then wait for half a second and retry, otherwise retry
1072 * after the e_d_tov time.
1073 */
fc_lport_error(struct fc_lport * lport,struct fc_frame * fp)1074 static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
1075 {
1076 unsigned long delay = 0;
1077 FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n",
1078 IS_ERR(fp) ? -PTR_ERR(fp) : 0, fc_lport_state(lport),
1079 lport->retry_count);
1080
1081 if (PTR_ERR(fp) == -FC_EX_CLOSED)
1082 return;
1083
1084 /*
1085 * Memory allocation failure, or the exchange timed out
1086 * or we received LS_RJT.
1087 * Retry after delay
1088 */
1089 if (lport->retry_count < lport->max_retry_count) {
1090 lport->retry_count++;
1091 if (!fp)
1092 delay = msecs_to_jiffies(500);
1093 else
1094 delay = msecs_to_jiffies(lport->e_d_tov);
1095
1096 schedule_delayed_work(&lport->retry_work, delay);
1097 } else
1098 fc_lport_enter_reset(lport);
1099 }
1100
1101 /**
1102 * fc_lport_ns_resp() - Handle response to a name server
1103 * registration exchange
1104 * @sp: current sequence in exchange
1105 * @fp: response frame
1106 * @lp_arg: Fibre Channel host port instance
1107 *
1108 * Locking Note: This function will be called without the lport lock
1109 * held, but it will lock, call an _enter_* function or fc_lport_error()
1110 * and then unlock the lport.
1111 */
fc_lport_ns_resp(struct fc_seq * sp,struct fc_frame * fp,void * lp_arg)1112 static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
1113 void *lp_arg)
1114 {
1115 struct fc_lport *lport = lp_arg;
1116 struct fc_frame_header *fh;
1117 struct fc_ct_hdr *ct;
1118
1119 FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
1120
1121 if (fp == ERR_PTR(-FC_EX_CLOSED))
1122 return;
1123
1124 mutex_lock(&lport->lp_mutex);
1125
1126 if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
1127 FC_LPORT_DBG(lport, "Received a name server response, "
1128 "but in state %s\n", fc_lport_state(lport));
1129 if (IS_ERR(fp))
1130 goto err;
1131 goto out;
1132 }
1133
1134 if (IS_ERR(fp)) {
1135 fc_lport_error(lport, fp);
1136 goto err;
1137 }
1138
1139 fh = fc_frame_header_get(fp);
1140 ct = fc_frame_payload_get(fp, sizeof(*ct));
1141
1142 if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1143 ct->ct_fs_type == FC_FST_DIR &&
1144 ct->ct_fs_subtype == FC_NS_SUBTYPE &&
1145 ntohs(ct->ct_cmd) == FC_FS_ACC)
1146 switch (lport->state) {
1147 case LPORT_ST_RNN_ID:
1148 fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
1149 break;
1150 case LPORT_ST_RSNN_NN:
1151 fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
1152 break;
1153 case LPORT_ST_RSPN_ID:
1154 fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1155 break;
1156 case LPORT_ST_RFT_ID:
1157 fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
1158 break;
1159 case LPORT_ST_RFF_ID:
1160 if (lport->fdmi_enabled)
1161 fc_lport_enter_fdmi(lport);
1162 else
1163 fc_lport_enter_scr(lport);
1164 break;
1165 default:
1166 /* should have already been caught by state checks */
1167 break;
1168 }
1169 else
1170 fc_lport_error(lport, fp);
1171 out:
1172 fc_frame_free(fp);
1173 err:
1174 mutex_unlock(&lport->lp_mutex);
1175 }
1176
1177 /**
1178 * fc_lport_ms_resp() - Handle response to a management server
1179 * exchange
1180 * @sp: current sequence in exchange
1181 * @fp: response frame
1182 * @lp_arg: Fibre Channel host port instance
1183 *
1184 * Locking Note: This function will be called without the lport lock
1185 * held, but it will lock, call an _enter_* function or fc_lport_error()
1186 * and then unlock the lport.
1187 */
fc_lport_ms_resp(struct fc_seq * sp,struct fc_frame * fp,void * lp_arg)1188 static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp,
1189 void *lp_arg)
1190 {
1191 struct fc_lport *lport = lp_arg;
1192 struct fc_frame_header *fh;
1193 struct fc_ct_hdr *ct;
1194
1195 FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp));
1196
1197 if (fp == ERR_PTR(-FC_EX_CLOSED))
1198 return;
1199
1200 mutex_lock(&lport->lp_mutex);
1201
1202 if (lport->state < LPORT_ST_RHBA || lport->state > LPORT_ST_DPRT) {
1203 FC_LPORT_DBG(lport, "Received a management server response, "
1204 "but in state %s\n", fc_lport_state(lport));
1205 if (IS_ERR(fp))
1206 goto err;
1207 goto out;
1208 }
1209
1210 if (IS_ERR(fp)) {
1211 fc_lport_error(lport, fp);
1212 goto err;
1213 }
1214
1215 fh = fc_frame_header_get(fp);
1216 ct = fc_frame_payload_get(fp, sizeof(*ct));
1217
1218 if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1219 ct->ct_fs_type == FC_FST_MGMT &&
1220 ct->ct_fs_subtype == FC_FDMI_SUBTYPE) {
1221 FC_LPORT_DBG(lport, "Received a management server response, "
1222 "reason=%d explain=%d\n",
1223 ct->ct_reason,
1224 ct->ct_explan);
1225
1226 switch (lport->state) {
1227 case LPORT_ST_RHBA:
1228 if (ntohs(ct->ct_cmd) == FC_FS_ACC)
1229 fc_lport_enter_ms(lport, LPORT_ST_RPA);
1230 else /* Error Skip RPA */
1231 fc_lport_enter_scr(lport);
1232 break;
1233 case LPORT_ST_RPA:
1234 fc_lport_enter_scr(lport);
1235 break;
1236 case LPORT_ST_DPRT:
1237 fc_lport_enter_ms(lport, LPORT_ST_RHBA);
1238 break;
1239 case LPORT_ST_DHBA:
1240 fc_lport_enter_ms(lport, LPORT_ST_DPRT);
1241 break;
1242 default:
1243 /* should have already been caught by state checks */
1244 break;
1245 }
1246 } else {
1247 /* Invalid Frame? */
1248 fc_lport_error(lport, fp);
1249 }
1250 out:
1251 fc_frame_free(fp);
1252 err:
1253 mutex_unlock(&lport->lp_mutex);
1254 }
1255
1256 /**
1257 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
1258 * @sp: current sequence in SCR exchange
1259 * @fp: response frame
1260 * @lp_arg: Fibre Channel lport port instance that sent the registration request
1261 *
1262 * Locking Note: This function will be called without the lport lock
1263 * held, but it will lock, call an _enter_* function or fc_lport_error
1264 * and then unlock the lport.
1265 */
fc_lport_scr_resp(struct fc_seq * sp,struct fc_frame * fp,void * lp_arg)1266 static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
1267 void *lp_arg)
1268 {
1269 struct fc_lport *lport = lp_arg;
1270 u8 op;
1271
1272 FC_LPORT_DBG(lport, "Received a SCR %s\n", fc_els_resp_type(fp));
1273
1274 if (fp == ERR_PTR(-FC_EX_CLOSED))
1275 return;
1276
1277 mutex_lock(&lport->lp_mutex);
1278
1279 if (lport->state != LPORT_ST_SCR) {
1280 FC_LPORT_DBG(lport, "Received a SCR response, but in state "
1281 "%s\n", fc_lport_state(lport));
1282 if (IS_ERR(fp))
1283 goto err;
1284 goto out;
1285 }
1286
1287 if (IS_ERR(fp)) {
1288 fc_lport_error(lport, fp);
1289 goto err;
1290 }
1291
1292 op = fc_frame_payload_op(fp);
1293 if (op == ELS_LS_ACC)
1294 fc_lport_enter_ready(lport);
1295 else
1296 fc_lport_error(lport, fp);
1297
1298 out:
1299 fc_frame_free(fp);
1300 err:
1301 mutex_unlock(&lport->lp_mutex);
1302 }
1303
1304 /**
1305 * fc_lport_enter_scr() - Send a SCR (State Change Register) request
1306 * @lport: The local port to register for state changes
1307 */
fc_lport_enter_scr(struct fc_lport * lport)1308 static void fc_lport_enter_scr(struct fc_lport *lport)
1309 {
1310 struct fc_frame *fp;
1311
1312 lockdep_assert_held(&lport->lp_mutex);
1313
1314 FC_LPORT_DBG(lport, "Entered SCR state from %s state\n",
1315 fc_lport_state(lport));
1316
1317 fc_lport_state_enter(lport, LPORT_ST_SCR);
1318
1319 fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr));
1320 if (!fp) {
1321 fc_lport_error(lport, fp);
1322 return;
1323 }
1324
1325 if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
1326 fc_lport_scr_resp, lport,
1327 2 * lport->r_a_tov))
1328 fc_lport_error(lport, NULL);
1329 }
1330
1331 /**
1332 * fc_lport_enter_ns() - register some object with the name server
1333 * @lport: Fibre Channel local port to register
1334 * @state: Local port state
1335 */
fc_lport_enter_ns(struct fc_lport * lport,enum fc_lport_state state)1336 static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
1337 {
1338 struct fc_frame *fp;
1339 enum fc_ns_req cmd;
1340 int size = sizeof(struct fc_ct_hdr);
1341 size_t len;
1342
1343 lockdep_assert_held(&lport->lp_mutex);
1344
1345 FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1346 fc_lport_state_names[state],
1347 fc_lport_state(lport));
1348
1349 fc_lport_state_enter(lport, state);
1350
1351 switch (state) {
1352 case LPORT_ST_RNN_ID:
1353 cmd = FC_NS_RNN_ID;
1354 size += sizeof(struct fc_ns_rn_id);
1355 break;
1356 case LPORT_ST_RSNN_NN:
1357 len = strnlen(fc_host_symbolic_name(lport->host), 255);
1358 /* if there is no symbolic name, skip to RFT_ID */
1359 if (!len)
1360 return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1361 cmd = FC_NS_RSNN_NN;
1362 size += sizeof(struct fc_ns_rsnn) + len;
1363 break;
1364 case LPORT_ST_RSPN_ID:
1365 len = strnlen(fc_host_symbolic_name(lport->host), 255);
1366 /* if there is no symbolic name, skip to RFT_ID */
1367 if (!len)
1368 return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1369 cmd = FC_NS_RSPN_ID;
1370 size += sizeof(struct fc_ns_rspn) + len;
1371 break;
1372 case LPORT_ST_RFT_ID:
1373 cmd = FC_NS_RFT_ID;
1374 size += sizeof(struct fc_ns_rft);
1375 break;
1376 case LPORT_ST_RFF_ID:
1377 cmd = FC_NS_RFF_ID;
1378 size += sizeof(struct fc_ns_rff_id);
1379 break;
1380 default:
1381 fc_lport_error(lport, NULL);
1382 return;
1383 }
1384
1385 fp = fc_frame_alloc(lport, size);
1386 if (!fp) {
1387 fc_lport_error(lport, fp);
1388 return;
1389 }
1390
1391 if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
1392 fc_lport_ns_resp,
1393 lport, 3 * lport->r_a_tov))
1394 fc_lport_error(lport, fp);
1395 }
1396
1397 static struct fc_rport_operations fc_lport_rport_ops = {
1398 .event_callback = fc_lport_rport_callback,
1399 };
1400
1401 /**
1402 * fc_rport_enter_dns() - Create a fc_rport for the name server
1403 * @lport: The local port requesting a remote port for the name server
1404 */
fc_lport_enter_dns(struct fc_lport * lport)1405 static void fc_lport_enter_dns(struct fc_lport *lport)
1406 {
1407 struct fc_rport_priv *rdata;
1408
1409 lockdep_assert_held(&lport->lp_mutex);
1410
1411 FC_LPORT_DBG(lport, "Entered DNS state from %s state\n",
1412 fc_lport_state(lport));
1413
1414 fc_lport_state_enter(lport, LPORT_ST_DNS);
1415
1416 mutex_lock(&lport->disc.disc_mutex);
1417 rdata = fc_rport_create(lport, FC_FID_DIR_SERV);
1418 mutex_unlock(&lport->disc.disc_mutex);
1419 if (!rdata)
1420 goto err;
1421
1422 rdata->ops = &fc_lport_rport_ops;
1423 fc_rport_login(rdata);
1424 return;
1425
1426 err:
1427 fc_lport_error(lport, NULL);
1428 }
1429
1430 /**
1431 * fc_lport_enter_ms() - management server commands
1432 * @lport: Fibre Channel local port to register
1433 * @state: Local port state
1434 */
fc_lport_enter_ms(struct fc_lport * lport,enum fc_lport_state state)1435 static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state)
1436 {
1437 struct fc_frame *fp;
1438 enum fc_fdmi_req cmd;
1439 int size = sizeof(struct fc_ct_hdr);
1440 size_t len;
1441 int numattrs;
1442
1443 lockdep_assert_held(&lport->lp_mutex);
1444
1445 FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1446 fc_lport_state_names[state],
1447 fc_lport_state(lport));
1448
1449 fc_lport_state_enter(lport, state);
1450
1451 switch (state) {
1452 case LPORT_ST_RHBA:
1453 cmd = FC_FDMI_RHBA;
1454 /* Number of HBA Attributes */
1455 numattrs = 10;
1456 len = sizeof(struct fc_fdmi_rhba);
1457 len -= sizeof(struct fc_fdmi_attr_entry);
1458 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
1459 len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
1460 len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
1461 len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
1462 len += FC_FDMI_HBA_ATTR_MODEL_LEN;
1463 len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
1464 len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
1465 len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
1466 len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
1467 len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
1468 len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
1469
1470 size += len;
1471 break;
1472 case LPORT_ST_RPA:
1473 cmd = FC_FDMI_RPA;
1474 /* Number of Port Attributes */
1475 numattrs = 6;
1476 len = sizeof(struct fc_fdmi_rpa);
1477 len -= sizeof(struct fc_fdmi_attr_entry);
1478 len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
1479 len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
1480 len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
1481 len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
1482 len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
1483 len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
1484 len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
1485
1486 size += len;
1487 break;
1488 case LPORT_ST_DPRT:
1489 cmd = FC_FDMI_DPRT;
1490 len = sizeof(struct fc_fdmi_dprt);
1491 size += len;
1492 break;
1493 case LPORT_ST_DHBA:
1494 cmd = FC_FDMI_DHBA;
1495 len = sizeof(struct fc_fdmi_dhba);
1496 size += len;
1497 break;
1498 default:
1499 fc_lport_error(lport, NULL);
1500 return;
1501 }
1502
1503 FC_LPORT_DBG(lport, "Cmd=0x%x Len %d size %d\n",
1504 cmd, (int)len, size);
1505 fp = fc_frame_alloc(lport, size);
1506 if (!fp) {
1507 fc_lport_error(lport, fp);
1508 return;
1509 }
1510
1511 if (!lport->tt.elsct_send(lport, FC_FID_MGMT_SERV, fp, cmd,
1512 fc_lport_ms_resp,
1513 lport, 3 * lport->r_a_tov))
1514 fc_lport_error(lport, fp);
1515 }
1516
1517 /**
1518 * fc_rport_enter_fdmi() - Create a fc_rport for the management server
1519 * @lport: The local port requesting a remote port for the management server
1520 */
fc_lport_enter_fdmi(struct fc_lport * lport)1521 static void fc_lport_enter_fdmi(struct fc_lport *lport)
1522 {
1523 struct fc_rport_priv *rdata;
1524
1525 lockdep_assert_held(&lport->lp_mutex);
1526
1527 FC_LPORT_DBG(lport, "Entered FDMI state from %s state\n",
1528 fc_lport_state(lport));
1529
1530 fc_lport_state_enter(lport, LPORT_ST_FDMI);
1531
1532 mutex_lock(&lport->disc.disc_mutex);
1533 rdata = fc_rport_create(lport, FC_FID_MGMT_SERV);
1534 mutex_unlock(&lport->disc.disc_mutex);
1535 if (!rdata)
1536 goto err;
1537
1538 rdata->ops = &fc_lport_rport_ops;
1539 fc_rport_login(rdata);
1540 return;
1541
1542 err:
1543 fc_lport_error(lport, NULL);
1544 }
1545
1546 /**
1547 * fc_lport_timeout() - Handler for the retry_work timer
1548 * @work: The work struct of the local port
1549 */
fc_lport_timeout(struct work_struct * work)1550 static void fc_lport_timeout(struct work_struct *work)
1551 {
1552 struct fc_lport *lport =
1553 container_of(work, struct fc_lport,
1554 retry_work.work);
1555
1556 mutex_lock(&lport->lp_mutex);
1557
1558 switch (lport->state) {
1559 case LPORT_ST_DISABLED:
1560 break;
1561 case LPORT_ST_READY:
1562 break;
1563 case LPORT_ST_RESET:
1564 break;
1565 case LPORT_ST_FLOGI:
1566 fc_lport_enter_flogi(lport);
1567 break;
1568 case LPORT_ST_DNS:
1569 fc_lport_enter_dns(lport);
1570 break;
1571 case LPORT_ST_RNN_ID:
1572 case LPORT_ST_RSNN_NN:
1573 case LPORT_ST_RSPN_ID:
1574 case LPORT_ST_RFT_ID:
1575 case LPORT_ST_RFF_ID:
1576 fc_lport_enter_ns(lport, lport->state);
1577 break;
1578 case LPORT_ST_FDMI:
1579 fc_lport_enter_fdmi(lport);
1580 break;
1581 case LPORT_ST_RHBA:
1582 case LPORT_ST_RPA:
1583 case LPORT_ST_DHBA:
1584 case LPORT_ST_DPRT:
1585 FC_LPORT_DBG(lport, "Skipping lport state %s to SCR\n",
1586 fc_lport_state(lport));
1587 fallthrough;
1588 case LPORT_ST_SCR:
1589 fc_lport_enter_scr(lport);
1590 break;
1591 case LPORT_ST_LOGO:
1592 fc_lport_enter_logo(lport);
1593 break;
1594 }
1595
1596 mutex_unlock(&lport->lp_mutex);
1597 }
1598
1599 /**
1600 * fc_lport_logo_resp() - Handle response to LOGO request
1601 * @sp: The sequence that the LOGO was on
1602 * @fp: The LOGO frame
1603 * @lp_arg: The lport port that received the LOGO request
1604 *
1605 * Locking Note: This function will be called without the lport lock
1606 * held, but it will lock, call an _enter_* function or fc_lport_error()
1607 * and then unlock the lport.
1608 */
fc_lport_logo_resp(struct fc_seq * sp,struct fc_frame * fp,void * lp_arg)1609 void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1610 void *lp_arg)
1611 {
1612 struct fc_lport *lport = lp_arg;
1613 u8 op;
1614
1615 FC_LPORT_DBG(lport, "Received a LOGO %s\n", fc_els_resp_type(fp));
1616
1617 if (fp == ERR_PTR(-FC_EX_CLOSED))
1618 return;
1619
1620 mutex_lock(&lport->lp_mutex);
1621
1622 if (lport->state != LPORT_ST_LOGO) {
1623 FC_LPORT_DBG(lport, "Received a LOGO response, but in state "
1624 "%s\n", fc_lport_state(lport));
1625 if (IS_ERR(fp))
1626 goto err;
1627 goto out;
1628 }
1629
1630 if (IS_ERR(fp)) {
1631 fc_lport_error(lport, fp);
1632 goto err;
1633 }
1634
1635 op = fc_frame_payload_op(fp);
1636 if (op == ELS_LS_ACC)
1637 fc_lport_enter_disabled(lport);
1638 else
1639 fc_lport_error(lport, fp);
1640
1641 out:
1642 fc_frame_free(fp);
1643 err:
1644 mutex_unlock(&lport->lp_mutex);
1645 }
1646 EXPORT_SYMBOL(fc_lport_logo_resp);
1647
1648 /**
1649 * fc_rport_enter_logo() - Logout of the fabric
1650 * @lport: The local port to be logged out
1651 */
fc_lport_enter_logo(struct fc_lport * lport)1652 static void fc_lport_enter_logo(struct fc_lport *lport)
1653 {
1654 struct fc_frame *fp;
1655 struct fc_els_logo *logo;
1656
1657 lockdep_assert_held(&lport->lp_mutex);
1658
1659 FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n",
1660 fc_lport_state(lport));
1661
1662 fc_lport_state_enter(lport, LPORT_ST_LOGO);
1663 fc_vports_linkchange(lport);
1664
1665 fp = fc_frame_alloc(lport, sizeof(*logo));
1666 if (!fp) {
1667 fc_lport_error(lport, fp);
1668 return;
1669 }
1670
1671 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
1672 fc_lport_logo_resp, lport,
1673 2 * lport->r_a_tov))
1674 fc_lport_error(lport, NULL);
1675 }
1676
1677 /**
1678 * fc_lport_flogi_resp() - Handle response to FLOGI request
1679 * @sp: The sequence that the FLOGI was on
1680 * @fp: The FLOGI response frame
1681 * @lp_arg: The lport port that received the FLOGI response
1682 *
1683 * Locking Note: This function will be called without the lport lock
1684 * held, but it will lock, call an _enter_* function or fc_lport_error()
1685 * and then unlock the lport.
1686 */
fc_lport_flogi_resp(struct fc_seq * sp,struct fc_frame * fp,void * lp_arg)1687 void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1688 void *lp_arg)
1689 {
1690 struct fc_lport *lport = lp_arg;
1691 struct fc_frame_header *fh;
1692 struct fc_els_flogi *flp;
1693 u32 did;
1694 u16 csp_flags;
1695 unsigned int r_a_tov;
1696 unsigned int e_d_tov;
1697 u16 mfs;
1698
1699 FC_LPORT_DBG(lport, "Received a FLOGI %s\n", fc_els_resp_type(fp));
1700
1701 if (fp == ERR_PTR(-FC_EX_CLOSED))
1702 return;
1703
1704 mutex_lock(&lport->lp_mutex);
1705
1706 if (lport->state != LPORT_ST_FLOGI) {
1707 FC_LPORT_DBG(lport, "Received a FLOGI response, but in state "
1708 "%s\n", fc_lport_state(lport));
1709 if (IS_ERR(fp))
1710 goto err;
1711 goto out;
1712 }
1713
1714 if (IS_ERR(fp)) {
1715 fc_lport_error(lport, fp);
1716 goto err;
1717 }
1718
1719 fh = fc_frame_header_get(fp);
1720 did = fc_frame_did(fp);
1721 if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
1722 fc_frame_payload_op(fp) != ELS_LS_ACC) {
1723 FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
1724 fc_lport_error(lport, fp);
1725 goto out;
1726 }
1727
1728 flp = fc_frame_payload_get(fp, sizeof(*flp));
1729 if (!flp) {
1730 FC_LPORT_DBG(lport, "FLOGI bad response\n");
1731 fc_lport_error(lport, fp);
1732 goto out;
1733 }
1734
1735 mfs = ntohs(flp->fl_csp.sp_bb_data) &
1736 FC_SP_BB_DATA_MASK;
1737
1738 if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
1739 FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
1740 "lport->mfs:%u\n", mfs, lport->mfs);
1741 fc_lport_error(lport, fp);
1742 goto out;
1743 }
1744
1745 if (mfs <= lport->mfs) {
1746 lport->mfs = mfs;
1747 fc_host_maxframe_size(lport->host) = mfs;
1748 }
1749
1750 csp_flags = ntohs(flp->fl_csp.sp_features);
1751 r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1752 e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1753 if (csp_flags & FC_SP_FT_EDTR)
1754 e_d_tov /= 1000000;
1755
1756 lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1757
1758 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1759 if (e_d_tov > lport->e_d_tov)
1760 lport->e_d_tov = e_d_tov;
1761 lport->r_a_tov = 2 * lport->e_d_tov;
1762 fc_lport_set_port_id(lport, did, fp);
1763 printk(KERN_INFO "host%d: libfc: "
1764 "Port (%6.6x) entered "
1765 "point-to-point mode\n",
1766 lport->host->host_no, did);
1767 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1768 get_unaligned_be64(
1769 &flp->fl_wwpn),
1770 get_unaligned_be64(
1771 &flp->fl_wwnn));
1772 } else {
1773 if (e_d_tov > lport->e_d_tov)
1774 lport->e_d_tov = e_d_tov;
1775 if (r_a_tov > lport->r_a_tov)
1776 lport->r_a_tov = r_a_tov;
1777 fc_host_fabric_name(lport->host) =
1778 get_unaligned_be64(&flp->fl_wwnn);
1779 fc_lport_set_port_id(lport, did, fp);
1780 fc_lport_enter_dns(lport);
1781 }
1782
1783 out:
1784 fc_frame_free(fp);
1785 err:
1786 mutex_unlock(&lport->lp_mutex);
1787 }
1788 EXPORT_SYMBOL(fc_lport_flogi_resp);
1789
1790 /**
1791 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
1792 * @lport: Fibre Channel local port to be logged in to the fabric
1793 */
fc_lport_enter_flogi(struct fc_lport * lport)1794 static void fc_lport_enter_flogi(struct fc_lport *lport)
1795 {
1796 struct fc_frame *fp;
1797
1798 lockdep_assert_held(&lport->lp_mutex);
1799
1800 FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n",
1801 fc_lport_state(lport));
1802
1803 fc_lport_state_enter(lport, LPORT_ST_FLOGI);
1804
1805 if (lport->point_to_multipoint) {
1806 if (lport->port_id)
1807 fc_lport_enter_ready(lport);
1808 return;
1809 }
1810
1811 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
1812 if (!fp)
1813 return fc_lport_error(lport, fp);
1814
1815 if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
1816 lport->vport ? ELS_FDISC : ELS_FLOGI,
1817 fc_lport_flogi_resp, lport,
1818 lport->vport ? 2 * lport->r_a_tov :
1819 lport->e_d_tov))
1820 fc_lport_error(lport, NULL);
1821 }
1822
1823 /**
1824 * fc_lport_config() - Configure a fc_lport
1825 * @lport: The local port to be configured
1826 */
fc_lport_config(struct fc_lport * lport)1827 int fc_lport_config(struct fc_lport *lport)
1828 {
1829 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
1830 mutex_init(&lport->lp_mutex);
1831
1832 fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1833
1834 fc_lport_add_fc4_type(lport, FC_TYPE_FCP);
1835 fc_lport_add_fc4_type(lport, FC_TYPE_CT);
1836 fc_fc4_conf_lport_params(lport, FC_TYPE_FCP);
1837
1838 return 0;
1839 }
1840 EXPORT_SYMBOL(fc_lport_config);
1841
1842 /**
1843 * fc_lport_init() - Initialize the lport layer for a local port
1844 * @lport: The local port to initialize the exchange layer for
1845 */
fc_lport_init(struct fc_lport * lport)1846 int fc_lport_init(struct fc_lport *lport)
1847 {
1848 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
1849 fc_host_node_name(lport->host) = lport->wwnn;
1850 fc_host_port_name(lport->host) = lport->wwpn;
1851 fc_host_supported_classes(lport->host) = FC_COS_CLASS3;
1852 memset(fc_host_supported_fc4s(lport->host), 0,
1853 sizeof(fc_host_supported_fc4s(lport->host)));
1854 fc_host_supported_fc4s(lport->host)[2] = 1;
1855 fc_host_supported_fc4s(lport->host)[7] = 1;
1856
1857 /* This value is also unchanging */
1858 memset(fc_host_active_fc4s(lport->host), 0,
1859 sizeof(fc_host_active_fc4s(lport->host)));
1860 fc_host_active_fc4s(lport->host)[2] = 1;
1861 fc_host_active_fc4s(lport->host)[7] = 1;
1862 fc_host_maxframe_size(lport->host) = lport->mfs;
1863 fc_host_supported_speeds(lport->host) = 0;
1864 if (lport->link_supported_speeds & FC_PORTSPEED_1GBIT)
1865 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT;
1866 if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
1867 fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
1868 fc_fc4_add_lport(lport);
1869
1870 return 0;
1871 }
1872 EXPORT_SYMBOL(fc_lport_init);
1873
1874 /**
1875 * fc_lport_bsg_resp() - The common response handler for FC Passthrough requests
1876 * @sp: The sequence for the FC Passthrough response
1877 * @fp: The response frame
1878 * @info_arg: The BSG info that the response is for
1879 */
fc_lport_bsg_resp(struct fc_seq * sp,struct fc_frame * fp,void * info_arg)1880 static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
1881 void *info_arg)
1882 {
1883 struct fc_bsg_info *info = info_arg;
1884 struct bsg_job *job = info->job;
1885 struct fc_bsg_reply *bsg_reply = job->reply;
1886 struct fc_lport *lport = info->lport;
1887 struct fc_frame_header *fh;
1888 size_t len;
1889 void *buf;
1890
1891 if (IS_ERR(fp)) {
1892 bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
1893 -ECONNABORTED : -ETIMEDOUT;
1894 job->reply_len = sizeof(uint32_t);
1895 bsg_job_done(job, bsg_reply->result,
1896 bsg_reply->reply_payload_rcv_len);
1897 kfree(info);
1898 return;
1899 }
1900
1901 mutex_lock(&lport->lp_mutex);
1902 fh = fc_frame_header_get(fp);
1903 len = fr_len(fp) - sizeof(*fh);
1904 buf = fc_frame_payload_get(fp, 0);
1905
1906 if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
1907 /* Get the response code from the first frame payload */
1908 unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
1909 ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
1910 (unsigned short)fc_frame_payload_op(fp);
1911
1912 /* Save the reply status of the job */
1913 bsg_reply->reply_data.ctels_reply.status =
1914 (cmd == info->rsp_code) ?
1915 FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
1916 }
1917
1918 bsg_reply->reply_payload_rcv_len +=
1919 fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
1920 &info->offset, NULL);
1921
1922 if (fr_eof(fp) == FC_EOF_T &&
1923 (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1924 (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1925 if (bsg_reply->reply_payload_rcv_len >
1926 job->reply_payload.payload_len)
1927 bsg_reply->reply_payload_rcv_len =
1928 job->reply_payload.payload_len;
1929 bsg_reply->result = 0;
1930 bsg_job_done(job, bsg_reply->result,
1931 bsg_reply->reply_payload_rcv_len);
1932 kfree(info);
1933 }
1934 fc_frame_free(fp);
1935 mutex_unlock(&lport->lp_mutex);
1936 }
1937
1938 /**
1939 * fc_lport_els_request() - Send ELS passthrough request
1940 * @job: The BSG Passthrough job
1941 * @lport: The local port sending the request
1942 * @did: The destination port id
1943 * @tov: The timeout period (in ms)
1944 */
fc_lport_els_request(struct bsg_job * job,struct fc_lport * lport,u32 did,u32 tov)1945 static int fc_lport_els_request(struct bsg_job *job,
1946 struct fc_lport *lport,
1947 u32 did, u32 tov)
1948 {
1949 struct fc_bsg_info *info;
1950 struct fc_frame *fp;
1951 struct fc_frame_header *fh;
1952 char *pp;
1953 int len;
1954
1955 lockdep_assert_held(&lport->lp_mutex);
1956
1957 fp = fc_frame_alloc(lport, job->request_payload.payload_len);
1958 if (!fp)
1959 return -ENOMEM;
1960
1961 len = job->request_payload.payload_len;
1962 pp = fc_frame_payload_get(fp, len);
1963
1964 sg_copy_to_buffer(job->request_payload.sg_list,
1965 job->request_payload.sg_cnt,
1966 pp, len);
1967
1968 fh = fc_frame_header_get(fp);
1969 fh->fh_r_ctl = FC_RCTL_ELS_REQ;
1970 hton24(fh->fh_d_id, did);
1971 hton24(fh->fh_s_id, lport->port_id);
1972 fh->fh_type = FC_TYPE_ELS;
1973 hton24(fh->fh_f_ctl, FC_FCTL_REQ);
1974 fh->fh_cs_ctl = 0;
1975 fh->fh_df_ctl = 0;
1976 fh->fh_parm_offset = 0;
1977
1978 info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
1979 if (!info) {
1980 fc_frame_free(fp);
1981 return -ENOMEM;
1982 }
1983
1984 info->job = job;
1985 info->lport = lport;
1986 info->rsp_code = ELS_LS_ACC;
1987 info->nents = job->reply_payload.sg_cnt;
1988 info->sg = job->reply_payload.sg_list;
1989
1990 if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
1991 NULL, info, tov)) {
1992 kfree(info);
1993 return -ECOMM;
1994 }
1995 return 0;
1996 }
1997
1998 /**
1999 * fc_lport_ct_request() - Send CT Passthrough request
2000 * @job: The BSG Passthrough job
2001 * @lport: The local port sending the request
2002 * @did: The destination FC-ID
2003 * @tov: The timeout period to wait for the response
2004 */
fc_lport_ct_request(struct bsg_job * job,struct fc_lport * lport,u32 did,u32 tov)2005 static int fc_lport_ct_request(struct bsg_job *job,
2006 struct fc_lport *lport, u32 did, u32 tov)
2007 {
2008 struct fc_bsg_info *info;
2009 struct fc_frame *fp;
2010 struct fc_frame_header *fh;
2011 struct fc_ct_req *ct;
2012 size_t len;
2013
2014 lockdep_assert_held(&lport->lp_mutex);
2015
2016 fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
2017 job->request_payload.payload_len);
2018 if (!fp)
2019 return -ENOMEM;
2020
2021 len = job->request_payload.payload_len;
2022 ct = fc_frame_payload_get(fp, len);
2023
2024 sg_copy_to_buffer(job->request_payload.sg_list,
2025 job->request_payload.sg_cnt,
2026 ct, len);
2027
2028 fh = fc_frame_header_get(fp);
2029 fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
2030 hton24(fh->fh_d_id, did);
2031 hton24(fh->fh_s_id, lport->port_id);
2032 fh->fh_type = FC_TYPE_CT;
2033 hton24(fh->fh_f_ctl, FC_FCTL_REQ);
2034 fh->fh_cs_ctl = 0;
2035 fh->fh_df_ctl = 0;
2036 fh->fh_parm_offset = 0;
2037
2038 info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
2039 if (!info) {
2040 fc_frame_free(fp);
2041 return -ENOMEM;
2042 }
2043
2044 info->job = job;
2045 info->lport = lport;
2046 info->rsp_code = FC_FS_ACC;
2047 info->nents = job->reply_payload.sg_cnt;
2048 info->sg = job->reply_payload.sg_list;
2049
2050 if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
2051 NULL, info, tov)) {
2052 kfree(info);
2053 return -ECOMM;
2054 }
2055 return 0;
2056 }
2057
2058 /**
2059 * fc_lport_bsg_request() - The common entry point for sending
2060 * FC Passthrough requests
2061 * @job: The BSG passthrough job
2062 */
fc_lport_bsg_request(struct bsg_job * job)2063 int fc_lport_bsg_request(struct bsg_job *job)
2064 {
2065 struct fc_bsg_request *bsg_request = job->request;
2066 struct fc_bsg_reply *bsg_reply = job->reply;
2067 struct Scsi_Host *shost = fc_bsg_to_shost(job);
2068 struct fc_lport *lport = shost_priv(shost);
2069 struct fc_rport *rport;
2070 struct fc_rport_priv *rdata;
2071 int rc = -EINVAL;
2072 u32 did, tov;
2073
2074 bsg_reply->reply_payload_rcv_len = 0;
2075
2076 mutex_lock(&lport->lp_mutex);
2077
2078 switch (bsg_request->msgcode) {
2079 case FC_BSG_RPT_ELS:
2080 rport = fc_bsg_to_rport(job);
2081 if (!rport)
2082 break;
2083
2084 rdata = rport->dd_data;
2085 rc = fc_lport_els_request(job, lport, rport->port_id,
2086 rdata->e_d_tov);
2087 break;
2088
2089 case FC_BSG_RPT_CT:
2090 rport = fc_bsg_to_rport(job);
2091 if (!rport)
2092 break;
2093
2094 rdata = rport->dd_data;
2095 rc = fc_lport_ct_request(job, lport, rport->port_id,
2096 rdata->e_d_tov);
2097 break;
2098
2099 case FC_BSG_HST_CT:
2100 did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
2101 if (did == FC_FID_DIR_SERV) {
2102 rdata = lport->dns_rdata;
2103 if (!rdata)
2104 break;
2105 tov = rdata->e_d_tov;
2106 } else {
2107 rdata = fc_rport_lookup(lport, did);
2108 if (!rdata)
2109 break;
2110 tov = rdata->e_d_tov;
2111 kref_put(&rdata->kref, fc_rport_destroy);
2112 }
2113
2114 rc = fc_lport_ct_request(job, lport, did, tov);
2115 break;
2116
2117 case FC_BSG_HST_ELS_NOLOGIN:
2118 did = ntoh24(bsg_request->rqst_data.h_els.port_id);
2119 rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
2120 break;
2121 }
2122
2123 mutex_unlock(&lport->lp_mutex);
2124 return rc;
2125 }
2126 EXPORT_SYMBOL(fc_lport_bsg_request);
2127