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