2294 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.4 *5 * Maintained at www.Open-FCoE.org6 */7 8/*9 * RPORT GENERAL INFO10 *11 * This file contains all processing regarding fc_rports. It contains the12 * rport state machine and does all rport interaction with the transport class.13 * There should be no other places in libfc that interact directly with the14 * transport class in regards to adding and deleting rports.15 *16 * fc_rport's represent N_Port's within the fabric.17 */18 19/*20 * RPORT LOCKING21 *22 * The rport should never hold the rport mutex and then attempt to acquire23 * either the lport or disc mutexes. The rport's mutex is considered lesser24 * than both the lport's mutex and the disc mutex. Refer to fc_lport.c for25 * more comments on the hierarchy.26 *27 * The locking strategy is similar to the lport's strategy. The lock protects28 * the rport's states and is held and released by the entry points to the rport29 * block. All _enter_* functions correspond to rport states and expect the rport30 * mutex to be locked before calling them. This means that rports only handle31 * one request or response at a time, since they're not critical for the I/O32 * path this potential over-use of the mutex is acceptable.33 */34 35/*36 * RPORT REFERENCE COUNTING37 *38 * A rport reference should be taken when:39 * - an rport is allocated40 * - a workqueue item is scheduled41 * - an ELS request is send42 * The reference should be dropped when:43 * - the workqueue function has finished44 * - the ELS response is handled45 * - an rport is removed46 */47 48#include <linux/kernel.h>49#include <linux/spinlock.h>50#include <linux/interrupt.h>51#include <linux/slab.h>52#include <linux/rcupdate.h>53#include <linux/timer.h>54#include <linux/workqueue.h>55#include <linux/export.h>56#include <linux/rculist.h>57 58#include <linux/unaligned.h>59 60#include <scsi/libfc.h>61 62#include "fc_encode.h"63#include "fc_libfc.h"64 65static struct workqueue_struct *rport_event_queue;66 67static void fc_rport_enter_flogi(struct fc_rport_priv *);68static void fc_rport_enter_plogi(struct fc_rport_priv *);69static void fc_rport_enter_prli(struct fc_rport_priv *);70static void fc_rport_enter_rtv(struct fc_rport_priv *);71static void fc_rport_enter_ready(struct fc_rport_priv *);72static void fc_rport_enter_logo(struct fc_rport_priv *);73static void fc_rport_enter_adisc(struct fc_rport_priv *);74 75static void fc_rport_recv_plogi_req(struct fc_lport *, struct fc_frame *);76static void fc_rport_recv_prli_req(struct fc_rport_priv *, struct fc_frame *);77static void fc_rport_recv_prlo_req(struct fc_rport_priv *, struct fc_frame *);78static void fc_rport_recv_logo_req(struct fc_lport *, struct fc_frame *);79static void fc_rport_timeout(struct work_struct *);80static void fc_rport_error(struct fc_rport_priv *, int);81static void fc_rport_error_retry(struct fc_rport_priv *, int);82static void fc_rport_work(struct work_struct *);83 84static const char *fc_rport_state_names[] = {85 [RPORT_ST_INIT] = "Init",86 [RPORT_ST_FLOGI] = "FLOGI",87 [RPORT_ST_PLOGI_WAIT] = "PLOGI_WAIT",88 [RPORT_ST_PLOGI] = "PLOGI",89 [RPORT_ST_PRLI] = "PRLI",90 [RPORT_ST_RTV] = "RTV",91 [RPORT_ST_READY] = "Ready",92 [RPORT_ST_ADISC] = "ADISC",93 [RPORT_ST_DELETE] = "Delete",94};95 96/**97 * fc_rport_lookup() - Lookup a remote port by port_id98 * @lport: The local port to lookup the remote port on99 * @port_id: The remote port ID to look up100 *101 * The reference count of the fc_rport_priv structure is102 * increased by one.103 */104struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,105 u32 port_id)106{107 struct fc_rport_priv *rdata = NULL, *tmp_rdata;108 109 rcu_read_lock();110 list_for_each_entry_rcu(tmp_rdata, &lport->disc.rports, peers)111 if (tmp_rdata->ids.port_id == port_id &&112 kref_get_unless_zero(&tmp_rdata->kref)) {113 rdata = tmp_rdata;114 break;115 }116 rcu_read_unlock();117 return rdata;118}119EXPORT_SYMBOL(fc_rport_lookup);120 121/**122 * fc_rport_create() - Create a new remote port123 * @lport: The local port this remote port will be associated with124 * @port_id: The identifiers for the new remote port125 *126 * The remote port will start in the INIT state.127 */128struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id)129{130 struct fc_rport_priv *rdata;131 size_t rport_priv_size = sizeof(*rdata);132 133 lockdep_assert_held(&lport->disc.disc_mutex);134 135 rdata = fc_rport_lookup(lport, port_id);136 if (rdata) {137 kref_put(&rdata->kref, fc_rport_destroy);138 return rdata;139 }140 141 if (lport->rport_priv_size > 0)142 rport_priv_size = lport->rport_priv_size;143 rdata = kzalloc(rport_priv_size, GFP_KERNEL);144 if (!rdata)145 return NULL;146 147 rdata->ids.node_name = -1;148 rdata->ids.port_name = -1;149 rdata->ids.port_id = port_id;150 rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;151 152 kref_init(&rdata->kref);153 mutex_init(&rdata->rp_mutex);154 rdata->local_port = lport;155 rdata->rp_state = RPORT_ST_INIT;156 rdata->event = RPORT_EV_NONE;157 rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;158 rdata->e_d_tov = lport->e_d_tov;159 rdata->r_a_tov = lport->r_a_tov;160 rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;161 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);162 INIT_WORK(&rdata->event_work, fc_rport_work);163 if (port_id != FC_FID_DIR_SERV) {164 rdata->lld_event_callback = lport->tt.rport_event_callback;165 list_add_rcu(&rdata->peers, &lport->disc.rports);166 }167 return rdata;168}169EXPORT_SYMBOL(fc_rport_create);170 171/**172 * fc_rport_destroy() - Free a remote port after last reference is released173 * @kref: The remote port's kref174 */175void fc_rport_destroy(struct kref *kref)176{177 struct fc_rport_priv *rdata;178 179 rdata = container_of(kref, struct fc_rport_priv, kref);180 kfree_rcu(rdata, rcu);181}182EXPORT_SYMBOL(fc_rport_destroy);183 184/**185 * fc_rport_state() - Return a string identifying the remote port's state186 * @rdata: The remote port187 */188static const char *fc_rport_state(struct fc_rport_priv *rdata)189{190 const char *cp;191 192 cp = fc_rport_state_names[rdata->rp_state];193 if (!cp)194 cp = "Unknown";195 return cp;196}197 198/**199 * fc_set_rport_loss_tmo() - Set the remote port loss timeout200 * @rport: The remote port that gets a new timeout value201 * @timeout: The new timeout value (in seconds)202 */203void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)204{205 if (timeout)206 rport->dev_loss_tmo = timeout;207 else208 rport->dev_loss_tmo = 1;209}210EXPORT_SYMBOL(fc_set_rport_loss_tmo);211 212/**213 * fc_plogi_get_maxframe() - Get the maximum payload from the common service214 * parameters in a FLOGI frame215 * @flp: The FLOGI or PLOGI payload216 * @maxval: The maximum frame size upper limit; this may be less than what217 * is in the service parameters218 */219static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,220 unsigned int maxval)221{222 unsigned int mfs;223 224 /*225 * Get max payload from the common service parameters and the226 * class 3 receive data field size.227 */228 mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK;229 if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval)230 maxval = mfs;231 mfs = ntohs(flp->fl_cssp[3 - 1].cp_rdfs);232 if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < maxval)233 maxval = mfs;234 return maxval;235}236 237/**238 * fc_rport_state_enter() - Change the state of a remote port239 * @rdata: The remote port whose state should change240 * @new: The new state241 */242static void fc_rport_state_enter(struct fc_rport_priv *rdata,243 enum fc_rport_state new)244{245 lockdep_assert_held(&rdata->rp_mutex);246 247 if (rdata->rp_state != new)248 rdata->retries = 0;249 rdata->rp_state = new;250}251 252/**253 * fc_rport_work() - Handler for remote port events in the rport_event_queue254 * @work: Handle to the remote port being dequeued255 *256 * Reference counting: drops kref on return257 */258static void fc_rport_work(struct work_struct *work)259{260 u32 port_id;261 struct fc_rport_priv *rdata =262 container_of(work, struct fc_rport_priv, event_work);263 struct fc_rport_libfc_priv *rpriv;264 enum fc_rport_event event;265 struct fc_lport *lport = rdata->local_port;266 struct fc_rport_operations *rport_ops;267 struct fc_rport_identifiers ids;268 struct fc_rport *rport;269 struct fc4_prov *prov;270 u8 type;271 272 mutex_lock(&rdata->rp_mutex);273 event = rdata->event;274 rport_ops = rdata->ops;275 rport = rdata->rport;276 277 FC_RPORT_DBG(rdata, "work event %u\n", event);278 279 switch (event) {280 case RPORT_EV_READY:281 ids = rdata->ids;282 rdata->event = RPORT_EV_NONE;283 rdata->major_retries = 0;284 kref_get(&rdata->kref);285 mutex_unlock(&rdata->rp_mutex);286 287 if (!rport) {288 FC_RPORT_DBG(rdata, "No rport!\n");289 rport = fc_remote_port_add(lport->host, 0, &ids);290 }291 if (!rport) {292 FC_RPORT_DBG(rdata, "Failed to add the rport\n");293 fc_rport_logoff(rdata);294 kref_put(&rdata->kref, fc_rport_destroy);295 return;296 }297 mutex_lock(&rdata->rp_mutex);298 if (rdata->rport)299 FC_RPORT_DBG(rdata, "rport already allocated\n");300 rdata->rport = rport;301 rport->maxframe_size = rdata->maxframe_size;302 rport->supported_classes = rdata->supported_classes;303 304 rpriv = rport->dd_data;305 rpriv->local_port = lport;306 rpriv->rp_state = rdata->rp_state;307 rpriv->flags = rdata->flags;308 rpriv->e_d_tov = rdata->e_d_tov;309 rpriv->r_a_tov = rdata->r_a_tov;310 mutex_unlock(&rdata->rp_mutex);311 312 if (rport_ops && rport_ops->event_callback) {313 FC_RPORT_DBG(rdata, "callback ev %d\n", event);314 rport_ops->event_callback(lport, rdata, event);315 }316 if (rdata->lld_event_callback) {317 FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);318 rdata->lld_event_callback(lport, rdata, event);319 }320 kref_put(&rdata->kref, fc_rport_destroy);321 break;322 323 case RPORT_EV_FAILED:324 case RPORT_EV_LOGO:325 case RPORT_EV_STOP:326 if (rdata->prli_count) {327 mutex_lock(&fc_prov_mutex);328 for (type = 1; type < FC_FC4_PROV_SIZE; type++) {329 prov = fc_passive_prov[type];330 if (prov && prov->prlo)331 prov->prlo(rdata);332 }333 mutex_unlock(&fc_prov_mutex);334 }335 port_id = rdata->ids.port_id;336 mutex_unlock(&rdata->rp_mutex);337 338 if (rport_ops && rport_ops->event_callback) {339 FC_RPORT_DBG(rdata, "callback ev %d\n", event);340 rport_ops->event_callback(lport, rdata, event);341 }342 if (rdata->lld_event_callback) {343 FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);344 rdata->lld_event_callback(lport, rdata, event);345 }346 if (cancel_delayed_work_sync(&rdata->retry_work))347 kref_put(&rdata->kref, fc_rport_destroy);348 349 /*350 * Reset any outstanding exchanges before freeing rport.351 */352 lport->tt.exch_mgr_reset(lport, 0, port_id);353 lport->tt.exch_mgr_reset(lport, port_id, 0);354 355 if (rport) {356 rpriv = rport->dd_data;357 rpriv->rp_state = RPORT_ST_DELETE;358 mutex_lock(&rdata->rp_mutex);359 rdata->rport = NULL;360 mutex_unlock(&rdata->rp_mutex);361 fc_remote_port_delete(rport);362 }363 364 mutex_lock(&rdata->rp_mutex);365 if (rdata->rp_state == RPORT_ST_DELETE) {366 if (port_id == FC_FID_DIR_SERV) {367 rdata->event = RPORT_EV_NONE;368 mutex_unlock(&rdata->rp_mutex);369 kref_put(&rdata->kref, fc_rport_destroy);370 } else if ((rdata->flags & FC_RP_STARTED) &&371 rdata->major_retries <372 lport->max_rport_retry_count) {373 rdata->major_retries++;374 rdata->event = RPORT_EV_NONE;375 FC_RPORT_DBG(rdata, "work restart\n");376 fc_rport_enter_flogi(rdata);377 mutex_unlock(&rdata->rp_mutex);378 } else {379 mutex_unlock(&rdata->rp_mutex);380 FC_RPORT_DBG(rdata, "work delete\n");381 mutex_lock(&lport->disc.disc_mutex);382 list_del_rcu(&rdata->peers);383 mutex_unlock(&lport->disc.disc_mutex);384 kref_put(&rdata->kref, fc_rport_destroy);385 }386 } else {387 /*388 * Re-open for events. Reissue READY event if ready.389 */390 rdata->event = RPORT_EV_NONE;391 if (rdata->rp_state == RPORT_ST_READY) {392 FC_RPORT_DBG(rdata, "work reopen\n");393 fc_rport_enter_ready(rdata);394 }395 mutex_unlock(&rdata->rp_mutex);396 }397 break;398 399 default:400 mutex_unlock(&rdata->rp_mutex);401 break;402 }403 kref_put(&rdata->kref, fc_rport_destroy);404}405 406/**407 * fc_rport_login() - Start the remote port login state machine408 * @rdata: The remote port to be logged in to409 *410 * Initiates the RP state machine. It is called from the LP module.411 * This function will issue the following commands to the N_Port412 * identified by the FC ID provided.413 *414 * - PLOGI415 * - PRLI416 * - RTV417 *418 * Locking Note: Called without the rport lock held. This419 * function will hold the rport lock, call an _enter_*420 * function and then unlock the rport.421 *422 * This indicates the intent to be logged into the remote port.423 * If it appears we are already logged in, ADISC is used to verify424 * the setup.425 */426int fc_rport_login(struct fc_rport_priv *rdata)427{428 mutex_lock(&rdata->rp_mutex);429 430 if (rdata->flags & FC_RP_STARTED) {431 FC_RPORT_DBG(rdata, "port already started\n");432 mutex_unlock(&rdata->rp_mutex);433 return 0;434 }435 436 rdata->flags |= FC_RP_STARTED;437 switch (rdata->rp_state) {438 case RPORT_ST_READY:439 FC_RPORT_DBG(rdata, "ADISC port\n");440 fc_rport_enter_adisc(rdata);441 break;442 case RPORT_ST_DELETE:443 FC_RPORT_DBG(rdata, "Restart deleted port\n");444 break;445 case RPORT_ST_INIT:446 FC_RPORT_DBG(rdata, "Login to port\n");447 fc_rport_enter_flogi(rdata);448 break;449 default:450 FC_RPORT_DBG(rdata, "Login in progress, state %s\n",451 fc_rport_state(rdata));452 break;453 }454 mutex_unlock(&rdata->rp_mutex);455 456 return 0;457}458EXPORT_SYMBOL(fc_rport_login);459 460/**461 * fc_rport_enter_delete() - Schedule a remote port to be deleted462 * @rdata: The remote port to be deleted463 * @event: The event to report as the reason for deletion464 *465 * Allow state change into DELETE only once.466 *467 * Call queue_work only if there's no event already pending.468 * Set the new event so that the old pending event will not occur.469 * Since we have the mutex, even if fc_rport_work() is already started,470 * it'll see the new event.471 *472 * Reference counting: does not modify kref473 */474static void fc_rport_enter_delete(struct fc_rport_priv *rdata,475 enum fc_rport_event event)476{477 lockdep_assert_held(&rdata->rp_mutex);478 479 if (rdata->rp_state == RPORT_ST_DELETE)480 return;481 482 FC_RPORT_DBG(rdata, "Delete port\n");483 484 fc_rport_state_enter(rdata, RPORT_ST_DELETE);485 486 if (rdata->event == RPORT_EV_NONE) {487 kref_get(&rdata->kref);488 if (!queue_work(rport_event_queue, &rdata->event_work))489 kref_put(&rdata->kref, fc_rport_destroy);490 }491 492 rdata->event = event;493}494 495/**496 * fc_rport_logoff() - Logoff and remove a remote port497 * @rdata: The remote port to be logged off of498 *499 * Locking Note: Called without the rport lock held. This500 * function will hold the rport lock, call an _enter_*501 * function and then unlock the rport.502 */503int fc_rport_logoff(struct fc_rport_priv *rdata)504{505 struct fc_lport *lport = rdata->local_port;506 u32 port_id = rdata->ids.port_id;507 508 mutex_lock(&rdata->rp_mutex);509 510 FC_RPORT_DBG(rdata, "Remove port\n");511 512 rdata->flags &= ~FC_RP_STARTED;513 if (rdata->rp_state == RPORT_ST_DELETE) {514 FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");515 goto out;516 }517 /*518 * FC-LS states:519 * To explicitly Logout, the initiating Nx_Port shall terminate520 * other open Sequences that it initiated with the destination521 * Nx_Port prior to performing Logout.522 */523 lport->tt.exch_mgr_reset(lport, 0, port_id);524 lport->tt.exch_mgr_reset(lport, port_id, 0);525 526 fc_rport_enter_logo(rdata);527 528 /*529 * Change the state to Delete so that we discard530 * the response.531 */532 fc_rport_enter_delete(rdata, RPORT_EV_STOP);533out:534 mutex_unlock(&rdata->rp_mutex);535 return 0;536}537EXPORT_SYMBOL(fc_rport_logoff);538 539/**540 * fc_rport_enter_ready() - Transition to the RPORT_ST_READY state541 * @rdata: The remote port that is ready542 *543 * Reference counting: schedules workqueue, does not modify kref544 */545static void fc_rport_enter_ready(struct fc_rport_priv *rdata)546{547 lockdep_assert_held(&rdata->rp_mutex);548 549 fc_rport_state_enter(rdata, RPORT_ST_READY);550 551 FC_RPORT_DBG(rdata, "Port is Ready\n");552 553 kref_get(&rdata->kref);554 if (rdata->event == RPORT_EV_NONE &&555 !queue_work(rport_event_queue, &rdata->event_work))556 kref_put(&rdata->kref, fc_rport_destroy);557 558 rdata->event = RPORT_EV_READY;559}560 561/**562 * fc_rport_timeout() - Handler for the retry_work timer563 * @work: Handle to the remote port that has timed out564 *565 * Locking Note: Called without the rport lock held. This566 * function will hold the rport lock, call an _enter_*567 * function and then unlock the rport.568 *569 * Reference counting: Drops kref on return.570 */571static void fc_rport_timeout(struct work_struct *work)572{573 struct fc_rport_priv *rdata =574 container_of(work, struct fc_rport_priv, retry_work.work);575 576 mutex_lock(&rdata->rp_mutex);577 FC_RPORT_DBG(rdata, "Port timeout, state %s\n", fc_rport_state(rdata));578 579 switch (rdata->rp_state) {580 case RPORT_ST_FLOGI:581 fc_rport_enter_flogi(rdata);582 break;583 case RPORT_ST_PLOGI:584 fc_rport_enter_plogi(rdata);585 break;586 case RPORT_ST_PRLI:587 fc_rport_enter_prli(rdata);588 break;589 case RPORT_ST_RTV:590 fc_rport_enter_rtv(rdata);591 break;592 case RPORT_ST_ADISC:593 fc_rport_enter_adisc(rdata);594 break;595 case RPORT_ST_PLOGI_WAIT:596 case RPORT_ST_READY:597 case RPORT_ST_INIT:598 case RPORT_ST_DELETE:599 break;600 }601 602 mutex_unlock(&rdata->rp_mutex);603 kref_put(&rdata->kref, fc_rport_destroy);604}605 606/**607 * fc_rport_error() - Error handler, called once retries have been exhausted608 * @rdata: The remote port the error is happened on609 * @err: The error code610 *611 * Reference counting: does not modify kref612 */613static void fc_rport_error(struct fc_rport_priv *rdata, int err)614{615 struct fc_lport *lport = rdata->local_port;616 617 lockdep_assert_held(&rdata->rp_mutex);618 619 FC_RPORT_DBG(rdata, "Error %d in state %s, retries %d\n",620 -err, fc_rport_state(rdata), rdata->retries);621 622 switch (rdata->rp_state) {623 case RPORT_ST_FLOGI:624 rdata->flags &= ~FC_RP_STARTED;625 fc_rport_enter_delete(rdata, RPORT_EV_FAILED);626 break;627 case RPORT_ST_PLOGI:628 if (lport->point_to_multipoint) {629 rdata->flags &= ~FC_RP_STARTED;630 fc_rport_enter_delete(rdata, RPORT_EV_FAILED);631 } else632 fc_rport_enter_logo(rdata);633 break;634 case RPORT_ST_RTV:635 fc_rport_enter_ready(rdata);636 break;637 case RPORT_ST_PRLI:638 fc_rport_enter_plogi(rdata);639 break;640 case RPORT_ST_ADISC:641 fc_rport_enter_logo(rdata);642 break;643 case RPORT_ST_PLOGI_WAIT:644 case RPORT_ST_DELETE:645 case RPORT_ST_READY:646 case RPORT_ST_INIT:647 break;648 }649}650 651/**652 * fc_rport_error_retry() - Handler for remote port state retries653 * @rdata: The remote port whose state is to be retried654 * @err: The error code655 *656 * If the error was an exchange timeout retry immediately,657 * otherwise wait for E_D_TOV.658 *659 * Reference counting: increments kref when scheduling retry_work660 */661static void fc_rport_error_retry(struct fc_rport_priv *rdata, int err)662{663 unsigned long delay = msecs_to_jiffies(rdata->e_d_tov);664 665 lockdep_assert_held(&rdata->rp_mutex);666 667 /* make sure this isn't an FC_EX_CLOSED error, never retry those */668 if (err == -FC_EX_CLOSED)669 goto out;670 671 if (rdata->retries < rdata->local_port->max_rport_retry_count) {672 FC_RPORT_DBG(rdata, "Error %d in state %s, retrying\n",673 err, fc_rport_state(rdata));674 rdata->retries++;675 /* no additional delay on exchange timeouts */676 if (err == -FC_EX_TIMEOUT)677 delay = 0;678 kref_get(&rdata->kref);679 if (!schedule_delayed_work(&rdata->retry_work, delay))680 kref_put(&rdata->kref, fc_rport_destroy);681 return;682 }683 684out:685 fc_rport_error(rdata, err);686}687 688/**689 * fc_rport_login_complete() - Handle parameters and completion of p-mp login.690 * @rdata: The remote port which we logged into or which logged into us.691 * @fp: The FLOGI or PLOGI request or response frame692 *693 * Returns non-zero error if a problem is detected with the frame.694 * Does not free the frame.695 *696 * This is only used in point-to-multipoint mode for FIP currently.697 */698static int fc_rport_login_complete(struct fc_rport_priv *rdata,699 struct fc_frame *fp)700{701 struct fc_lport *lport = rdata->local_port;702 struct fc_els_flogi *flogi;703 unsigned int e_d_tov;704 u16 csp_flags;705 706 flogi = fc_frame_payload_get(fp, sizeof(*flogi));707 if (!flogi)708 return -EINVAL;709 710 csp_flags = ntohs(flogi->fl_csp.sp_features);711 712 if (fc_frame_payload_op(fp) == ELS_FLOGI) {713 if (csp_flags & FC_SP_FT_FPORT) {714 FC_RPORT_DBG(rdata, "Fabric bit set in FLOGI\n");715 return -EINVAL;716 }717 } else {718 719 /*720 * E_D_TOV is not valid on an incoming FLOGI request.721 */722 e_d_tov = ntohl(flogi->fl_csp.sp_e_d_tov);723 if (csp_flags & FC_SP_FT_EDTR)724 e_d_tov /= 1000000;725 if (e_d_tov > rdata->e_d_tov)726 rdata->e_d_tov = e_d_tov;727 }728 rdata->maxframe_size = fc_plogi_get_maxframe(flogi, lport->mfs);729 return 0;730}731 732/**733 * fc_rport_flogi_resp() - Handle response to FLOGI request for p-mp mode734 * @sp: The sequence that the FLOGI was on735 * @fp: The FLOGI response frame736 * @rp_arg: The remote port that received the FLOGI response737 */738static void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,739 void *rp_arg)740{741 struct fc_rport_priv *rdata = rp_arg;742 struct fc_lport *lport = rdata->local_port;743 struct fc_els_flogi *flogi;744 unsigned int r_a_tov;745 u8 opcode;746 int err = 0;747 748 FC_RPORT_DBG(rdata, "Received a FLOGI %s\n",749 IS_ERR(fp) ? "error" : fc_els_resp_type(fp));750 751 if (fp == ERR_PTR(-FC_EX_CLOSED))752 goto put;753 754 mutex_lock(&rdata->rp_mutex);755 756 if (rdata->rp_state != RPORT_ST_FLOGI) {757 FC_RPORT_DBG(rdata, "Received a FLOGI response, but in state "758 "%s\n", fc_rport_state(rdata));759 if (IS_ERR(fp))760 goto err;761 goto out;762 }763 764 if (IS_ERR(fp)) {765 fc_rport_error(rdata, PTR_ERR(fp));766 goto err;767 }768 opcode = fc_frame_payload_op(fp);769 if (opcode == ELS_LS_RJT) {770 struct fc_els_ls_rjt *rjt;771 772 rjt = fc_frame_payload_get(fp, sizeof(*rjt));773 FC_RPORT_DBG(rdata, "FLOGI ELS rejected, reason %x expl %x\n",774 rjt->er_reason, rjt->er_explan);775 err = -FC_EX_ELS_RJT;776 goto bad;777 } else if (opcode != ELS_LS_ACC) {778 FC_RPORT_DBG(rdata, "FLOGI ELS invalid opcode %x\n", opcode);779 err = -FC_EX_ELS_RJT;780 goto bad;781 }782 if (fc_rport_login_complete(rdata, fp)) {783 FC_RPORT_DBG(rdata, "FLOGI failed, no login\n");784 err = -FC_EX_INV_LOGIN;785 goto bad;786 }787 788 flogi = fc_frame_payload_get(fp, sizeof(*flogi));789 if (!flogi) {790 err = -FC_EX_ALLOC_ERR;791 goto bad;792 }793 r_a_tov = ntohl(flogi->fl_csp.sp_r_a_tov);794 if (r_a_tov > rdata->r_a_tov)795 rdata->r_a_tov = r_a_tov;796 797 if (rdata->ids.port_name < lport->wwpn)798 fc_rport_enter_plogi(rdata);799 else800 fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);801out:802 fc_frame_free(fp);803err:804 mutex_unlock(&rdata->rp_mutex);805put:806 kref_put(&rdata->kref, fc_rport_destroy);807 return;808bad:809 FC_RPORT_DBG(rdata, "Bad FLOGI response\n");810 fc_rport_error_retry(rdata, err);811 goto out;812}813 814/**815 * fc_rport_enter_flogi() - Send a FLOGI request to the remote port for p-mp816 * @rdata: The remote port to send a FLOGI to817 *818 * Reference counting: increments kref when sending ELS819 */820static void fc_rport_enter_flogi(struct fc_rport_priv *rdata)821{822 struct fc_lport *lport = rdata->local_port;823 struct fc_frame *fp;824 825 lockdep_assert_held(&rdata->rp_mutex);826 827 if (!lport->point_to_multipoint)828 return fc_rport_enter_plogi(rdata);829 830 FC_RPORT_DBG(rdata, "Entered FLOGI state from %s state\n",831 fc_rport_state(rdata));832 833 fc_rport_state_enter(rdata, RPORT_ST_FLOGI);834 835 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));836 if (!fp)837 return fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);838 839 kref_get(&rdata->kref);840 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_FLOGI,841 fc_rport_flogi_resp, rdata,842 2 * lport->r_a_tov)) {843 fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);844 kref_put(&rdata->kref, fc_rport_destroy);845 }846}847 848/**849 * fc_rport_recv_flogi_req() - Handle Fabric Login (FLOGI) request in p-mp mode850 * @lport: The local port that received the PLOGI request851 * @rx_fp: The PLOGI request frame852 *853 * Reference counting: drops kref on return854 */855static void fc_rport_recv_flogi_req(struct fc_lport *lport,856 struct fc_frame *rx_fp)857{858 struct fc_els_flogi *flp;859 struct fc_rport_priv *rdata;860 struct fc_frame *fp = rx_fp;861 struct fc_seq_els_data rjt_data;862 u32 sid;863 864 sid = fc_frame_sid(fp);865 866 FC_RPORT_ID_DBG(lport, sid, "Received FLOGI request\n");867 868 if (!lport->point_to_multipoint) {869 rjt_data.reason = ELS_RJT_UNSUP;870 rjt_data.explan = ELS_EXPL_NONE;871 goto reject;872 }873 874 flp = fc_frame_payload_get(fp, sizeof(*flp));875 if (!flp) {876 rjt_data.reason = ELS_RJT_LOGIC;877 rjt_data.explan = ELS_EXPL_INV_LEN;878 goto reject;879 }880 881 rdata = fc_rport_lookup(lport, sid);882 if (!rdata) {883 rjt_data.reason = ELS_RJT_FIP;884 rjt_data.explan = ELS_EXPL_NOT_NEIGHBOR;885 goto reject;886 }887 mutex_lock(&rdata->rp_mutex);888 889 FC_RPORT_DBG(rdata, "Received FLOGI in %s state\n",890 fc_rport_state(rdata));891 892 switch (rdata->rp_state) {893 case RPORT_ST_INIT:894 /*895 * If received the FLOGI request on RPORT which is INIT state896 * (means not transition to FLOGI either fc_rport timeout897 * function didn;t trigger or this end hasn;t received898 * beacon yet from other end. In that case only, allow RPORT899 * state machine to continue, otherwise fall through which900 * causes the code to send reject response.901 * NOTE; Not checking for FIP->state such as VNMP_UP or902 * VNMP_CLAIM because if FIP state is not one of those,903 * RPORT wouldn;t have created and 'rport_lookup' would have904 * failed anyway in that case.905 */906 break;907 case RPORT_ST_DELETE:908 mutex_unlock(&rdata->rp_mutex);909 rjt_data.reason = ELS_RJT_FIP;910 rjt_data.explan = ELS_EXPL_NOT_NEIGHBOR;911 goto reject_put;912 case RPORT_ST_FLOGI:913 case RPORT_ST_PLOGI_WAIT:914 case RPORT_ST_PLOGI:915 break;916 case RPORT_ST_PRLI:917 case RPORT_ST_RTV:918 case RPORT_ST_READY:919 case RPORT_ST_ADISC:920 /*921 * Set the remote port to be deleted and to then restart.922 * This queues work to be sure exchanges are reset.923 */924 fc_rport_enter_delete(rdata, RPORT_EV_LOGO);925 mutex_unlock(&rdata->rp_mutex);926 rjt_data.reason = ELS_RJT_BUSY;927 rjt_data.explan = ELS_EXPL_NONE;928 goto reject_put;929 }930 if (fc_rport_login_complete(rdata, fp)) {931 mutex_unlock(&rdata->rp_mutex);932 rjt_data.reason = ELS_RJT_LOGIC;933 rjt_data.explan = ELS_EXPL_NONE;934 goto reject_put;935 }936 937 fp = fc_frame_alloc(lport, sizeof(*flp));938 if (!fp)939 goto out;940 941 fc_flogi_fill(lport, fp);942 flp = fc_frame_payload_get(fp, sizeof(*flp));943 flp->fl_cmd = ELS_LS_ACC;944 945 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);946 lport->tt.frame_send(lport, fp);947 948 /*949 * Do not proceed with the state machine if our950 * FLOGI has crossed with an FLOGI from the951 * remote port; wait for the FLOGI response instead.952 */953 if (rdata->rp_state != RPORT_ST_FLOGI) {954 if (rdata->ids.port_name < lport->wwpn)955 fc_rport_enter_plogi(rdata);956 else957 fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);958 }959out:960 mutex_unlock(&rdata->rp_mutex);961 kref_put(&rdata->kref, fc_rport_destroy);962 fc_frame_free(rx_fp);963 return;964 965reject_put:966 kref_put(&rdata->kref, fc_rport_destroy);967reject:968 fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);969 fc_frame_free(rx_fp);970}971 972/**973 * fc_rport_plogi_resp() - Handler for ELS PLOGI responses974 * @sp: The sequence the PLOGI is on975 * @fp: The PLOGI response frame976 * @rdata_arg: The remote port that sent the PLOGI response977 *978 * Locking Note: This function will be called without the rport lock979 * held, but it will lock, call an _enter_* function or fc_rport_error980 * and then unlock the rport.981 */982static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,983 void *rdata_arg)984{985 struct fc_rport_priv *rdata = rdata_arg;986 struct fc_lport *lport = rdata->local_port;987 struct fc_els_flogi *plp = NULL;988 u16 csp_seq;989 u16 cssp_seq;990 u8 op;991 992 FC_RPORT_DBG(rdata, "Received a PLOGI %s\n", fc_els_resp_type(fp));993 994 if (fp == ERR_PTR(-FC_EX_CLOSED))995 goto put;996 997 mutex_lock(&rdata->rp_mutex);998 999 if (rdata->rp_state != RPORT_ST_PLOGI) {1000 FC_RPORT_DBG(rdata, "Received a PLOGI response, but in state "1001 "%s\n", fc_rport_state(rdata));1002 if (IS_ERR(fp))1003 goto err;1004 goto out;1005 }1006 1007 if (IS_ERR(fp)) {1008 fc_rport_error_retry(rdata, PTR_ERR(fp));1009 goto err;1010 }1011 1012 op = fc_frame_payload_op(fp);1013 if (op == ELS_LS_ACC &&1014 (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {1015 rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);1016 rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);1017 1018 /* save plogi response sp_features for further reference */1019 rdata->sp_features = ntohs(plp->fl_csp.sp_features);1020 1021 if (lport->point_to_multipoint)1022 fc_rport_login_complete(rdata, fp);1023 csp_seq = ntohs(plp->fl_csp.sp_tot_seq);1024 cssp_seq = ntohs(plp->fl_cssp[3 - 1].cp_con_seq);1025 if (cssp_seq < csp_seq)1026 csp_seq = cssp_seq;1027 rdata->max_seq = csp_seq;1028 rdata->maxframe_size = fc_plogi_get_maxframe(plp, lport->mfs);1029 fc_rport_enter_prli(rdata);1030 } else {1031 struct fc_els_ls_rjt *rjt;1032 1033 rjt = fc_frame_payload_get(fp, sizeof(*rjt));1034 if (!rjt)1035 FC_RPORT_DBG(rdata, "PLOGI bad response\n");1036 else1037 FC_RPORT_DBG(rdata, "PLOGI ELS rejected, reason %x expl %x\n",1038 rjt->er_reason, rjt->er_explan);1039 fc_rport_error_retry(rdata, -FC_EX_ELS_RJT);1040 }1041out:1042 fc_frame_free(fp);1043err:1044 mutex_unlock(&rdata->rp_mutex);1045put:1046 kref_put(&rdata->kref, fc_rport_destroy);1047}1048 1049static bool1050fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)1051{1052 if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)1053 return true;1054 if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&1055 (lport->service_params & FCP_SPPF_INIT_FCN))1056 return true;1057 if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&1058 (lport->service_params & FCP_SPPF_TARG_FCN))1059 return true;1060 return false;1061}1062 1063/**1064 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request1065 * @rdata: The remote port to send a PLOGI to1066 *1067 * Reference counting: increments kref when sending ELS1068 */1069static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)1070{1071 struct fc_lport *lport = rdata->local_port;1072 struct fc_frame *fp;1073 1074 lockdep_assert_held(&rdata->rp_mutex);1075 1076 if (!fc_rport_compatible_roles(lport, rdata)) {1077 FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");1078 fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);1079 return;1080 }1081 1082 FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",1083 fc_rport_state(rdata));1084 1085 fc_rport_state_enter(rdata, RPORT_ST_PLOGI);1086 1087 rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;1088 fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));1089 if (!fp) {1090 FC_RPORT_DBG(rdata, "%s frame alloc failed\n", __func__);1091 fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);1092 return;1093 }1094 rdata->e_d_tov = lport->e_d_tov;1095 1096 kref_get(&rdata->kref);1097 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,1098 fc_rport_plogi_resp, rdata,1099 2 * lport->r_a_tov)) {1100 fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);1101 kref_put(&rdata->kref, fc_rport_destroy);1102 }1103}1104 1105/**1106 * fc_rport_prli_resp() - Process Login (PRLI) response handler1107 * @sp: The sequence the PRLI response was on1108 * @fp: The PRLI response frame1109 * @rdata_arg: The remote port that sent the PRLI response1110 *1111 * Locking Note: This function will be called without the rport lock1112 * held, but it will lock, call an _enter_* function or fc_rport_error1113 * and then unlock the rport.1114 */1115static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,1116 void *rdata_arg)1117{1118 struct fc_rport_priv *rdata = rdata_arg;1119 struct {1120 struct fc_els_prli prli;1121 struct fc_els_spp spp;1122 } *pp;1123 struct fc_els_spp temp_spp;1124 struct fc_els_ls_rjt *rjt;1125 struct fc4_prov *prov;1126 u32 roles = FC_RPORT_ROLE_UNKNOWN;1127 u32 fcp_parm = 0;1128 u8 op;1129 enum fc_els_spp_resp resp_code;1130 1131 FC_RPORT_DBG(rdata, "Received a PRLI %s\n", fc_els_resp_type(fp));1132 1133 if (fp == ERR_PTR(-FC_EX_CLOSED))1134 goto put;1135 1136 mutex_lock(&rdata->rp_mutex);1137 1138 if (rdata->rp_state != RPORT_ST_PRLI) {1139 FC_RPORT_DBG(rdata, "Received a PRLI response, but in state "1140 "%s\n", fc_rport_state(rdata));1141 if (IS_ERR(fp))1142 goto err;1143 goto out;1144 }1145 1146 if (IS_ERR(fp)) {1147 fc_rport_error_retry(rdata, PTR_ERR(fp));1148 goto err;1149 }1150 1151 /* reinitialize remote port roles */1152 rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;1153 1154 op = fc_frame_payload_op(fp);1155 if (op == ELS_LS_ACC) {1156 pp = fc_frame_payload_get(fp, sizeof(*pp));1157 if (!pp) {1158 fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR);1159 goto out;1160 }1161 1162 resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK);1163 FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x spp_type 0x%x\n",1164 pp->spp.spp_flags, pp->spp.spp_type);1165 1166 rdata->spp_type = pp->spp.spp_type;1167 if (resp_code != FC_SPP_RESP_ACK) {1168 if (resp_code == FC_SPP_RESP_CONF)1169 fc_rport_error(rdata, -FC_EX_SEQ_ERR);1170 else1171 fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR);1172 goto out;1173 }1174 if (pp->prli.prli_spp_len < sizeof(pp->spp)) {1175 fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR);1176 goto out;1177 }1178 1179 fcp_parm = ntohl(pp->spp.spp_params);1180 if (fcp_parm & FCP_SPPF_RETRY)1181 rdata->flags |= FC_RP_FLAGS_RETRY;1182 if (fcp_parm & FCP_SPPF_CONF_COMPL)1183 rdata->flags |= FC_RP_FLAGS_CONF_REQ;1184 1185 /*1186 * Call prli provider if we should act as a target1187 */1188 if (rdata->spp_type < FC_FC4_PROV_SIZE) {1189 prov = fc_passive_prov[rdata->spp_type];1190 if (prov) {1191 memset(&temp_spp, 0, sizeof(temp_spp));1192 prov->prli(rdata, pp->prli.prli_spp_len,1193 &pp->spp, &temp_spp);1194 }1195 }1196 /*1197 * Check if the image pair could be established1198 */1199 if (rdata->spp_type != FC_TYPE_FCP ||1200 !(pp->spp.spp_flags & FC_SPP_EST_IMG_PAIR)) {1201 /*1202 * Nope; we can't use this port as a target.1203 */1204 fcp_parm &= ~FCP_SPPF_TARG_FCN;1205 }1206 rdata->supported_classes = FC_COS_CLASS3;1207 if (fcp_parm & FCP_SPPF_INIT_FCN)1208 roles |= FC_RPORT_ROLE_FCP_INITIATOR;1209 if (fcp_parm & FCP_SPPF_TARG_FCN)1210 roles |= FC_RPORT_ROLE_FCP_TARGET;1211 1212 rdata->ids.roles = roles;1213 fc_rport_enter_rtv(rdata);1214 1215 } else {1216 rjt = fc_frame_payload_get(fp, sizeof(*rjt));1217 if (!rjt)1218 FC_RPORT_DBG(rdata, "PRLI bad response\n");1219 else {1220 FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n",1221 rjt->er_reason, rjt->er_explan);1222 if (rjt->er_reason == ELS_RJT_UNAB &&1223 rjt->er_explan == ELS_EXPL_PLOGI_REQD) {1224 fc_rport_enter_plogi(rdata);1225 goto out;1226 }1227 }1228 fc_rport_error_retry(rdata, FC_EX_ELS_RJT);1229 }1230 1231out:1232 fc_frame_free(fp);1233err:1234 mutex_unlock(&rdata->rp_mutex);1235put:1236 kref_put(&rdata->kref, fc_rport_destroy);1237}1238 1239/**1240 * fc_rport_enter_prli() - Send Process Login (PRLI) request1241 * @rdata: The remote port to send the PRLI request to1242 *1243 * Reference counting: increments kref when sending ELS1244 */1245static void fc_rport_enter_prli(struct fc_rport_priv *rdata)1246{1247 struct fc_lport *lport = rdata->local_port;1248 struct {1249 struct fc_els_prli prli;1250 struct fc_els_spp spp;1251 } *pp;1252 struct fc_frame *fp;1253 struct fc4_prov *prov;1254 1255 lockdep_assert_held(&rdata->rp_mutex);1256 1257 /*1258 * If the rport is one of the well known addresses1259 * we skip PRLI and RTV and go straight to READY.1260 */1261 if (rdata->ids.port_id >= FC_FID_DOM_MGR) {1262 fc_rport_enter_ready(rdata);1263 return;1264 }1265 1266 /*1267 * And if the local port does not support the initiator function1268 * there's no need to send a PRLI, either.1269 */1270 if (!(lport->service_params & FCP_SPPF_INIT_FCN)) {1271 fc_rport_enter_ready(rdata);1272 return;1273 }1274 1275 FC_RPORT_DBG(rdata, "Port entered PRLI state from %s state\n",1276 fc_rport_state(rdata));1277 1278 fc_rport_state_enter(rdata, RPORT_ST_PRLI);1279 1280 fp = fc_frame_alloc(lport, sizeof(*pp));1281 if (!fp) {1282 fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);1283 return;1284 }1285 1286 fc_prli_fill(lport, fp);1287 1288 prov = fc_passive_prov[FC_TYPE_FCP];1289 if (prov) {1290 pp = fc_frame_payload_get(fp, sizeof(*pp));1291 prov->prli(rdata, sizeof(pp->spp), NULL, &pp->spp);1292 }1293 1294 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rdata->ids.port_id,1295 fc_host_port_id(lport->host), FC_TYPE_ELS,1296 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);1297 1298 kref_get(&rdata->kref);1299 if (!fc_exch_seq_send(lport, fp, fc_rport_prli_resp,1300 NULL, rdata, 2 * lport->r_a_tov)) {1301 fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);1302 kref_put(&rdata->kref, fc_rport_destroy);1303 }1304}1305 1306/**1307 * fc_rport_rtv_resp() - Handler for Request Timeout Value (RTV) responses1308 * @sp: The sequence the RTV was on1309 * @fp: The RTV response frame1310 * @rdata_arg: The remote port that sent the RTV response1311 *1312 * Many targets don't seem to support this.1313 *1314 * Locking Note: This function will be called without the rport lock1315 * held, but it will lock, call an _enter_* function or fc_rport_error1316 * and then unlock the rport.1317 */1318static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,1319 void *rdata_arg)1320{1321 struct fc_rport_priv *rdata = rdata_arg;1322 u8 op;1323 1324 FC_RPORT_DBG(rdata, "Received a RTV %s\n", fc_els_resp_type(fp));1325 1326 if (fp == ERR_PTR(-FC_EX_CLOSED))1327 goto put;1328 1329 mutex_lock(&rdata->rp_mutex);1330 1331 if (rdata->rp_state != RPORT_ST_RTV) {1332 FC_RPORT_DBG(rdata, "Received a RTV response, but in state "1333 "%s\n", fc_rport_state(rdata));1334 if (IS_ERR(fp))1335 goto err;1336 goto out;1337 }1338 1339 if (IS_ERR(fp)) {1340 fc_rport_error(rdata, PTR_ERR(fp));1341 goto err;1342 }1343 1344 op = fc_frame_payload_op(fp);1345 if (op == ELS_LS_ACC) {1346 struct fc_els_rtv_acc *rtv;1347 u32 toq;1348 u32 tov;1349 1350 rtv = fc_frame_payload_get(fp, sizeof(*rtv));1351 if (rtv) {1352 toq = ntohl(rtv->rtv_toq);1353 tov = ntohl(rtv->rtv_r_a_tov);1354 if (tov == 0)1355 tov = 1;1356 if (tov > rdata->r_a_tov)1357 rdata->r_a_tov = tov;1358 tov = ntohl(rtv->rtv_e_d_tov);1359 if (toq & FC_ELS_RTV_EDRES)1360 tov /= 1000000;1361 if (tov == 0)1362 tov = 1;1363 if (tov > rdata->e_d_tov)1364 rdata->e_d_tov = tov;1365 }1366 }1367 1368 fc_rport_enter_ready(rdata);1369 1370out:1371 fc_frame_free(fp);1372err:1373 mutex_unlock(&rdata->rp_mutex);1374put:1375 kref_put(&rdata->kref, fc_rport_destroy);1376}1377 1378/**1379 * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request1380 * @rdata: The remote port to send the RTV request to1381 *1382 * Reference counting: increments kref when sending ELS1383 */1384static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)1385{1386 struct fc_frame *fp;1387 struct fc_lport *lport = rdata->local_port;1388 1389 lockdep_assert_held(&rdata->rp_mutex);1390 1391 FC_RPORT_DBG(rdata, "Port entered RTV state from %s state\n",1392 fc_rport_state(rdata));1393 1394 fc_rport_state_enter(rdata, RPORT_ST_RTV);1395 1396 fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));1397 if (!fp) {1398 fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);1399 return;1400 }1401 1402 kref_get(&rdata->kref);1403 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,1404 fc_rport_rtv_resp, rdata,1405 2 * lport->r_a_tov)) {1406 fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);1407 kref_put(&rdata->kref, fc_rport_destroy);1408 }1409}1410 1411/**1412 * fc_rport_recv_rtv_req() - Handler for Read Timeout Value (RTV) requests1413 * @rdata: The remote port that sent the RTV request1414 * @in_fp: The RTV request frame1415 */1416static void fc_rport_recv_rtv_req(struct fc_rport_priv *rdata,1417 struct fc_frame *in_fp)1418{1419 struct fc_lport *lport = rdata->local_port;1420 struct fc_frame *fp;1421 struct fc_els_rtv_acc *rtv;1422 struct fc_seq_els_data rjt_data;1423 1424 lockdep_assert_held(&rdata->rp_mutex);1425 lockdep_assert_held(&lport->lp_mutex);1426 1427 FC_RPORT_DBG(rdata, "Received RTV request\n");1428 1429 fp = fc_frame_alloc(lport, sizeof(*rtv));1430 if (!fp) {1431 rjt_data.reason = ELS_RJT_UNAB;1432 rjt_data.explan = ELS_EXPL_INSUF_RES;1433 fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);1434 goto drop;1435 }1436 rtv = fc_frame_payload_get(fp, sizeof(*rtv));1437 rtv->rtv_cmd = ELS_LS_ACC;1438 rtv->rtv_r_a_tov = htonl(lport->r_a_tov);1439 rtv->rtv_e_d_tov = htonl(lport->e_d_tov);1440 rtv->rtv_toq = 0;1441 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);1442 lport->tt.frame_send(lport, fp);1443drop:1444 fc_frame_free(in_fp);1445}1446 1447/**1448 * fc_rport_logo_resp() - Handler for logout (LOGO) responses1449 * @sp: The sequence the LOGO was on1450 * @fp: The LOGO response frame1451 * @rdata_arg: The remote port1452 */1453static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,1454 void *rdata_arg)1455{1456 struct fc_rport_priv *rdata = rdata_arg;1457 struct fc_lport *lport = rdata->local_port;1458 1459 FC_RPORT_ID_DBG(lport, fc_seq_exch(sp)->did,1460 "Received a LOGO %s\n", fc_els_resp_type(fp));1461 if (!IS_ERR(fp))1462 fc_frame_free(fp);1463 kref_put(&rdata->kref, fc_rport_destroy);1464}1465 1466/**1467 * fc_rport_enter_logo() - Send a logout (LOGO) request1468 * @rdata: The remote port to send the LOGO request to1469 *1470 * Reference counting: increments kref when sending ELS1471 */1472static void fc_rport_enter_logo(struct fc_rport_priv *rdata)1473{1474 struct fc_lport *lport = rdata->local_port;1475 struct fc_frame *fp;1476 1477 lockdep_assert_held(&rdata->rp_mutex);1478 1479 FC_RPORT_DBG(rdata, "Port sending LOGO from %s state\n",1480 fc_rport_state(rdata));1481 1482 fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));1483 if (!fp)1484 return;1485 kref_get(&rdata->kref);1486 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,1487 fc_rport_logo_resp, rdata, 0))1488 kref_put(&rdata->kref, fc_rport_destroy);1489}1490 1491/**1492 * fc_rport_adisc_resp() - Handler for Address Discovery (ADISC) responses1493 * @sp: The sequence the ADISC response was on1494 * @fp: The ADISC response frame1495 * @rdata_arg: The remote port that sent the ADISC response1496 *1497 * Locking Note: This function will be called without the rport lock1498 * held, but it will lock, call an _enter_* function or fc_rport_error1499 * and then unlock the rport.1500 */1501static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp,1502 void *rdata_arg)1503{1504 struct fc_rport_priv *rdata = rdata_arg;1505 struct fc_els_adisc *adisc;1506 u8 op;1507 1508 FC_RPORT_DBG(rdata, "Received a ADISC response\n");1509 1510 if (fp == ERR_PTR(-FC_EX_CLOSED))1511 goto put;1512 1513 mutex_lock(&rdata->rp_mutex);1514 1515 if (rdata->rp_state != RPORT_ST_ADISC) {1516 FC_RPORT_DBG(rdata, "Received a ADISC resp but in state %s\n",1517 fc_rport_state(rdata));1518 if (IS_ERR(fp))1519 goto err;1520 goto out;1521 }1522 1523 if (IS_ERR(fp)) {1524 fc_rport_error(rdata, PTR_ERR(fp));1525 goto err;1526 }1527 1528 /*1529 * If address verification failed. Consider us logged out of the rport.1530 * Since the rport is still in discovery, we want to be1531 * logged in, so go to PLOGI state. Otherwise, go back to READY.1532 */1533 op = fc_frame_payload_op(fp);1534 adisc = fc_frame_payload_get(fp, sizeof(*adisc));1535 if (op != ELS_LS_ACC || !adisc ||1536 ntoh24(adisc->adisc_port_id) != rdata->ids.port_id ||1537 get_unaligned_be64(&adisc->adisc_wwpn) != rdata->ids.port_name ||1538 get_unaligned_be64(&adisc->adisc_wwnn) != rdata->ids.node_name) {1539 FC_RPORT_DBG(rdata, "ADISC error or mismatch\n");1540 fc_rport_enter_flogi(rdata);1541 } else {1542 FC_RPORT_DBG(rdata, "ADISC OK\n");1543 fc_rport_enter_ready(rdata);1544 }1545out:1546 fc_frame_free(fp);1547err:1548 mutex_unlock(&rdata->rp_mutex);1549put:1550 kref_put(&rdata->kref, fc_rport_destroy);1551}1552 1553/**1554 * fc_rport_enter_adisc() - Send Address Discover (ADISC) request1555 * @rdata: The remote port to send the ADISC request to1556 *1557 * Reference counting: increments kref when sending ELS1558 */1559static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)1560{1561 struct fc_lport *lport = rdata->local_port;1562 struct fc_frame *fp;1563 1564 lockdep_assert_held(&rdata->rp_mutex);1565 1566 FC_RPORT_DBG(rdata, "sending ADISC from %s state\n",1567 fc_rport_state(rdata));1568 1569 fc_rport_state_enter(rdata, RPORT_ST_ADISC);1570 1571 fp = fc_frame_alloc(lport, sizeof(struct fc_els_adisc));1572 if (!fp) {1573 fc_rport_error_retry(rdata, -FC_EX_ALLOC_ERR);1574 return;1575 }1576 kref_get(&rdata->kref);1577 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,1578 fc_rport_adisc_resp, rdata,1579 2 * lport->r_a_tov)) {1580 fc_rport_error_retry(rdata, -FC_EX_XMIT_ERR);1581 kref_put(&rdata->kref, fc_rport_destroy);1582 }1583}1584 1585/**1586 * fc_rport_recv_adisc_req() - Handler for Address Discovery (ADISC) requests1587 * @rdata: The remote port that sent the ADISC request1588 * @in_fp: The ADISC request frame1589 */1590static void fc_rport_recv_adisc_req(struct fc_rport_priv *rdata,1591 struct fc_frame *in_fp)1592{1593 struct fc_lport *lport = rdata->local_port;1594 struct fc_frame *fp;1595 struct fc_els_adisc *adisc;1596 struct fc_seq_els_data rjt_data;1597 1598 lockdep_assert_held(&rdata->rp_mutex);1599 lockdep_assert_held(&lport->lp_mutex);1600 1601 FC_RPORT_DBG(rdata, "Received ADISC request\n");1602 1603 adisc = fc_frame_payload_get(in_fp, sizeof(*adisc));1604 if (!adisc) {1605 rjt_data.reason = ELS_RJT_PROT;1606 rjt_data.explan = ELS_EXPL_INV_LEN;1607 fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);1608 goto drop;1609 }1610 1611 fp = fc_frame_alloc(lport, sizeof(*adisc));1612 if (!fp)1613 goto drop;1614 fc_adisc_fill(lport, fp);1615 adisc = fc_frame_payload_get(fp, sizeof(*adisc));1616 adisc->adisc_cmd = ELS_LS_ACC;1617 fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);1618 lport->tt.frame_send(lport, fp);1619drop:1620 fc_frame_free(in_fp);1621}1622 1623/**1624 * fc_rport_recv_rls_req() - Handle received Read Link Status request1625 * @rdata: The remote port that sent the RLS request1626 * @rx_fp: The PRLI request frame1627 */1628static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,1629 struct fc_frame *rx_fp)1630 1631{1632 struct fc_lport *lport = rdata->local_port;1633 struct fc_frame *fp;1634 struct fc_els_rls *rls;1635 struct fc_els_rls_resp *rsp;1636 struct fc_els_lesb *lesb;1637 struct fc_seq_els_data rjt_data;1638 struct fc_host_statistics *hst;1639 1640 lockdep_assert_held(&rdata->rp_mutex);1641 1642 FC_RPORT_DBG(rdata, "Received RLS request while in state %s\n",1643 fc_rport_state(rdata));1644 1645 rls = fc_frame_payload_get(rx_fp, sizeof(*rls));1646 if (!rls) {1647 rjt_data.reason = ELS_RJT_PROT;1648 rjt_data.explan = ELS_EXPL_INV_LEN;1649 goto out_rjt;1650 }1651 1652 fp = fc_frame_alloc(lport, sizeof(*rsp));1653 if (!fp) {1654 rjt_data.reason = ELS_RJT_UNAB;1655 rjt_data.explan = ELS_EXPL_INSUF_RES;1656 goto out_rjt;1657 }1658 1659 rsp = fc_frame_payload_get(fp, sizeof(*rsp));1660 memset(rsp, 0, sizeof(*rsp));1661 rsp->rls_cmd = ELS_LS_ACC;1662 lesb = &rsp->rls_lesb;1663 if (lport->tt.get_lesb) {1664 /* get LESB from LLD if it supports it */1665 lport->tt.get_lesb(lport, lesb);1666 } else {1667 fc_get_host_stats(lport->host);1668 hst = &lport->host_stats;1669 lesb->lesb_link_fail = htonl(hst->link_failure_count);1670 lesb->lesb_sync_loss = htonl(hst->loss_of_sync_count);1671 lesb->lesb_sig_loss = htonl(hst->loss_of_signal_count);1672 lesb->lesb_prim_err = htonl(hst->prim_seq_protocol_err_count);1673 lesb->lesb_inv_word = htonl(hst->invalid_tx_word_count);1674 lesb->lesb_inv_crc = htonl(hst->invalid_crc_count);1675 }1676 1677 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);1678 lport->tt.frame_send(lport, fp);1679 goto out;1680 1681out_rjt:1682 fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);1683out:1684 fc_frame_free(rx_fp);1685}1686 1687/**1688 * fc_rport_recv_els_req() - Handler for validated ELS requests1689 * @lport: The local port that received the ELS request1690 * @fp: The ELS request frame1691 *1692 * Handle incoming ELS requests that require port login.1693 * The ELS opcode has already been validated by the caller.1694 *1695 * Reference counting: does not modify kref1696 */1697static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)1698{1699 struct fc_rport_priv *rdata;1700 struct fc_seq_els_data els_data;1701 1702 lockdep_assert_held(&lport->lp_mutex);1703 1704 rdata = fc_rport_lookup(lport, fc_frame_sid(fp));1705 if (!rdata) {1706 FC_RPORT_ID_DBG(lport, fc_frame_sid(fp),1707 "Received ELS 0x%02x from non-logged-in port\n",1708 fc_frame_payload_op(fp));1709 goto reject;1710 }1711 1712 mutex_lock(&rdata->rp_mutex);1713 1714 switch (rdata->rp_state) {1715 case RPORT_ST_PRLI:1716 case RPORT_ST_RTV:1717 case RPORT_ST_READY:1718 case RPORT_ST_ADISC:1719 break;1720 case RPORT_ST_PLOGI:1721 if (fc_frame_payload_op(fp) == ELS_PRLI) {1722 FC_RPORT_DBG(rdata, "Reject ELS PRLI "1723 "while in state %s\n",1724 fc_rport_state(rdata));1725 mutex_unlock(&rdata->rp_mutex);1726 kref_put(&rdata->kref, fc_rport_destroy);1727 goto busy;1728 }1729 fallthrough;1730 default:1731 FC_RPORT_DBG(rdata,1732 "Reject ELS 0x%02x while in state %s\n",1733 fc_frame_payload_op(fp), fc_rport_state(rdata));1734 mutex_unlock(&rdata->rp_mutex);1735 kref_put(&rdata->kref, fc_rport_destroy);1736 goto reject;1737 }1738 1739 switch (fc_frame_payload_op(fp)) {1740 case ELS_PRLI:1741 fc_rport_recv_prli_req(rdata, fp);1742 break;1743 case ELS_PRLO:1744 fc_rport_recv_prlo_req(rdata, fp);1745 break;1746 case ELS_ADISC:1747 fc_rport_recv_adisc_req(rdata, fp);1748 break;1749 case ELS_RRQ:1750 fc_seq_els_rsp_send(fp, ELS_RRQ, NULL);1751 fc_frame_free(fp);1752 break;1753 case ELS_REC:1754 fc_seq_els_rsp_send(fp, ELS_REC, NULL);1755 fc_frame_free(fp);1756 break;1757 case ELS_RLS:1758 fc_rport_recv_rls_req(rdata, fp);1759 break;1760 case ELS_RTV:1761 fc_rport_recv_rtv_req(rdata, fp);1762 break;1763 default:1764 fc_frame_free(fp); /* can't happen */1765 break;1766 }1767 1768 mutex_unlock(&rdata->rp_mutex);1769 kref_put(&rdata->kref, fc_rport_destroy);1770 return;1771 1772reject:1773 els_data.reason = ELS_RJT_UNAB;1774 els_data.explan = ELS_EXPL_PLOGI_REQD;1775 fc_seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);1776 fc_frame_free(fp);1777 return;1778 1779busy:1780 els_data.reason = ELS_RJT_BUSY;1781 els_data.explan = ELS_EXPL_NONE;1782 fc_seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);1783 fc_frame_free(fp);1784 return;1785}1786 1787/**1788 * fc_rport_recv_req() - Handler for requests1789 * @lport: The local port that received the request1790 * @fp: The request frame1791 *1792 * Reference counting: does not modify kref1793 */1794void fc_rport_recv_req(struct fc_lport *lport, struct fc_frame *fp)1795{1796 struct fc_seq_els_data els_data;1797 1798 lockdep_assert_held(&lport->lp_mutex);1799 1800 /*1801 * Handle FLOGI, PLOGI and LOGO requests separately, since they1802 * don't require prior login.1803 * Check for unsupported opcodes first and reject them.1804 * For some ops, it would be incorrect to reject with "PLOGI required".1805 */1806 switch (fc_frame_payload_op(fp)) {1807 case ELS_FLOGI:1808 fc_rport_recv_flogi_req(lport, fp);1809 break;1810 case ELS_PLOGI:1811 fc_rport_recv_plogi_req(lport, fp);1812 break;1813 case ELS_LOGO:1814 fc_rport_recv_logo_req(lport, fp);1815 break;1816 case ELS_PRLI:1817 case ELS_PRLO:1818 case ELS_ADISC:1819 case ELS_RRQ:1820 case ELS_REC:1821 case ELS_RLS:1822 case ELS_RTV:1823 fc_rport_recv_els_req(lport, fp);1824 break;1825 default:1826 els_data.reason = ELS_RJT_UNSUP;1827 els_data.explan = ELS_EXPL_NONE;1828 fc_seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);1829 fc_frame_free(fp);1830 break;1831 }1832}1833EXPORT_SYMBOL(fc_rport_recv_req);1834 1835/**1836 * fc_rport_recv_plogi_req() - Handler for Port Login (PLOGI) requests1837 * @lport: The local port that received the PLOGI request1838 * @rx_fp: The PLOGI request frame1839 *1840 * Reference counting: increments kref on return1841 */1842static void fc_rport_recv_plogi_req(struct fc_lport *lport,1843 struct fc_frame *rx_fp)1844{1845 struct fc_disc *disc;1846 struct fc_rport_priv *rdata;1847 struct fc_frame *fp = rx_fp;1848 struct fc_els_flogi *pl;1849 struct fc_seq_els_data rjt_data;1850 u32 sid;1851 1852 lockdep_assert_held(&lport->lp_mutex);1853 1854 sid = fc_frame_sid(fp);1855 1856 FC_RPORT_ID_DBG(lport, sid, "Received PLOGI request\n");1857 1858 pl = fc_frame_payload_get(fp, sizeof(*pl));1859 if (!pl) {1860 FC_RPORT_ID_DBG(lport, sid, "Received PLOGI too short\n");1861 rjt_data.reason = ELS_RJT_PROT;1862 rjt_data.explan = ELS_EXPL_INV_LEN;1863 goto reject;1864 }1865 1866 disc = &lport->disc;1867 mutex_lock(&disc->disc_mutex);1868 rdata = fc_rport_create(lport, sid);1869 if (!rdata) {1870 mutex_unlock(&disc->disc_mutex);1871 rjt_data.reason = ELS_RJT_UNAB;1872 rjt_data.explan = ELS_EXPL_INSUF_RES;1873 goto reject;1874 }1875 1876 mutex_lock(&rdata->rp_mutex);1877 mutex_unlock(&disc->disc_mutex);1878 1879 rdata->ids.port_name = get_unaligned_be64(&pl->fl_wwpn);1880 rdata->ids.node_name = get_unaligned_be64(&pl->fl_wwnn);1881 1882 /*1883 * If the rport was just created, possibly due to the incoming PLOGI,1884 * set the state appropriately and accept the PLOGI.1885 *1886 * If we had also sent a PLOGI, and if the received PLOGI is from a1887 * higher WWPN, we accept it, otherwise an LS_RJT is sent with reason1888 * "command already in progress".1889 *1890 * XXX TBD: If the session was ready before, the PLOGI should result in1891 * all outstanding exchanges being reset.1892 */1893 switch (rdata->rp_state) {1894 case RPORT_ST_INIT:1895 FC_RPORT_DBG(rdata, "Received PLOGI in INIT state\n");1896 break;1897 case RPORT_ST_PLOGI_WAIT:1898 FC_RPORT_DBG(rdata, "Received PLOGI in PLOGI_WAIT state\n");1899 break;1900 case RPORT_ST_PLOGI:1901 FC_RPORT_DBG(rdata, "Received PLOGI in PLOGI state\n");1902 if (rdata->ids.port_name < lport->wwpn) {1903 mutex_unlock(&rdata->rp_mutex);1904 rjt_data.reason = ELS_RJT_INPROG;1905 rjt_data.explan = ELS_EXPL_NONE;1906 goto reject;1907 }1908 break;1909 case RPORT_ST_PRLI:1910 case RPORT_ST_RTV:1911 case RPORT_ST_READY:1912 case RPORT_ST_ADISC:1913 FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "1914 "- ignored for now\n", rdata->rp_state);1915 /* XXX TBD - should reset */1916 break;1917 case RPORT_ST_FLOGI:1918 case RPORT_ST_DELETE:1919 FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",1920 fc_rport_state(rdata));1921 mutex_unlock(&rdata->rp_mutex);1922 rjt_data.reason = ELS_RJT_BUSY;1923 rjt_data.explan = ELS_EXPL_NONE;1924 goto reject;1925 }1926 if (!fc_rport_compatible_roles(lport, rdata)) {1927 FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");1928 mutex_unlock(&rdata->rp_mutex);1929 rjt_data.reason = ELS_RJT_LOGIC;1930 rjt_data.explan = ELS_EXPL_NONE;1931 goto reject;1932 }1933 1934 /*1935 * Get session payload size from incoming PLOGI.1936 */1937 rdata->maxframe_size = fc_plogi_get_maxframe(pl, lport->mfs);1938 1939 /*1940 * Send LS_ACC. If this fails, the originator should retry.1941 */1942 fp = fc_frame_alloc(lport, sizeof(*pl));1943 if (!fp)1944 goto out;1945 1946 fc_plogi_fill(lport, fp, ELS_LS_ACC);1947 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);1948 lport->tt.frame_send(lport, fp);1949 fc_rport_enter_prli(rdata);1950out:1951 mutex_unlock(&rdata->rp_mutex);1952 fc_frame_free(rx_fp);1953 return;1954 1955reject:1956 fc_seq_els_rsp_send(fp, ELS_LS_RJT, &rjt_data);1957 fc_frame_free(fp);1958}1959 1960/**1961 * fc_rport_recv_prli_req() - Handler for process login (PRLI) requests1962 * @rdata: The remote port that sent the PRLI request1963 * @rx_fp: The PRLI request frame1964 */1965static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,1966 struct fc_frame *rx_fp)1967{1968 struct fc_lport *lport = rdata->local_port;1969 struct fc_frame *fp;1970 struct {1971 struct fc_els_prli prli;1972 struct fc_els_spp spp;1973 } *pp;1974 struct fc_els_spp *rspp; /* request service param page */1975 struct fc_els_spp *spp; /* response spp */1976 unsigned int len;1977 unsigned int plen;1978 enum fc_els_spp_resp resp;1979 struct fc_seq_els_data rjt_data;1980 struct fc4_prov *prov;1981 1982 lockdep_assert_held(&rdata->rp_mutex);1983 1984 FC_RPORT_DBG(rdata, "Received PRLI request while in state %s\n",1985 fc_rport_state(rdata));1986 1987 len = fr_len(rx_fp) - sizeof(struct fc_frame_header);1988 pp = fc_frame_payload_get(rx_fp, sizeof(*pp));1989 if (!pp)1990 goto reject_len;1991 plen = ntohs(pp->prli.prli_len);1992 if ((plen % 4) != 0 || plen > len || plen < 16)1993 goto reject_len;1994 if (plen < len)1995 len = plen;1996 plen = pp->prli.prli_spp_len;1997 if ((plen % 4) != 0 || plen < sizeof(*spp) ||1998 plen > len || len < sizeof(*pp) || plen < 12)1999 goto reject_len;2000 rspp = &pp->spp;2001 2002 fp = fc_frame_alloc(lport, len);2003 if (!fp) {2004 rjt_data.reason = ELS_RJT_UNAB;2005 rjt_data.explan = ELS_EXPL_INSUF_RES;2006 goto reject;2007 }2008 pp = fc_frame_payload_get(fp, len);2009 WARN_ON(!pp);2010 memset(pp, 0, len);2011 pp->prli.prli_cmd = ELS_LS_ACC;2012 pp->prli.prli_spp_len = plen;2013 pp->prli.prli_len = htons(len);2014 len -= sizeof(struct fc_els_prli);2015 2016 /*2017 * Go through all the service parameter pages and build2018 * response. If plen indicates longer SPP than standard,2019 * use that. The entire response has been pre-cleared above.2020 */2021 spp = &pp->spp;2022 mutex_lock(&fc_prov_mutex);2023 while (len >= plen) {2024 rdata->spp_type = rspp->spp_type;2025 spp->spp_type = rspp->spp_type;2026 spp->spp_type_ext = rspp->spp_type_ext;2027 resp = 0;2028 2029 if (rspp->spp_type < FC_FC4_PROV_SIZE) {2030 enum fc_els_spp_resp active = 0, passive = 0;2031 2032 prov = fc_active_prov[rspp->spp_type];2033 if (prov)2034 active = prov->prli(rdata, plen, rspp, spp);2035 prov = fc_passive_prov[rspp->spp_type];2036 if (prov)2037 passive = prov->prli(rdata, plen, rspp, spp);2038 if (!active || passive == FC_SPP_RESP_ACK)2039 resp = passive;2040 else2041 resp = active;2042 FC_RPORT_DBG(rdata, "PRLI rspp type %x "2043 "active %x passive %x\n",2044 rspp->spp_type, active, passive);2045 }2046 if (!resp) {2047 if (spp->spp_flags & FC_SPP_EST_IMG_PAIR)2048 resp |= FC_SPP_RESP_CONF;2049 else2050 resp |= FC_SPP_RESP_INVL;2051 }2052 spp->spp_flags |= resp;2053 len -= plen;2054 rspp = (struct fc_els_spp *)((char *)rspp + plen);2055 spp = (struct fc_els_spp *)((char *)spp + plen);2056 }2057 mutex_unlock(&fc_prov_mutex);2058 2059 /*2060 * Send LS_ACC. If this fails, the originator should retry.2061 */2062 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);2063 lport->tt.frame_send(lport, fp);2064 2065 goto drop;2066 2067reject_len:2068 rjt_data.reason = ELS_RJT_PROT;2069 rjt_data.explan = ELS_EXPL_INV_LEN;2070reject:2071 fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);2072drop:2073 fc_frame_free(rx_fp);2074}2075 2076/**2077 * fc_rport_recv_prlo_req() - Handler for process logout (PRLO) requests2078 * @rdata: The remote port that sent the PRLO request2079 * @rx_fp: The PRLO request frame2080 */2081static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,2082 struct fc_frame *rx_fp)2083{2084 struct fc_lport *lport = rdata->local_port;2085 struct fc_frame *fp;2086 struct {2087 struct fc_els_prlo prlo;2088 struct fc_els_spp spp;2089 } *pp;2090 struct fc_els_spp *rspp; /* request service param page */2091 struct fc_els_spp *spp; /* response spp */2092 unsigned int len;2093 unsigned int plen;2094 struct fc_seq_els_data rjt_data;2095 2096 lockdep_assert_held(&rdata->rp_mutex);2097 2098 FC_RPORT_DBG(rdata, "Received PRLO request while in state %s\n",2099 fc_rport_state(rdata));2100 2101 len = fr_len(rx_fp) - sizeof(struct fc_frame_header);2102 pp = fc_frame_payload_get(rx_fp, sizeof(*pp));2103 if (!pp)2104 goto reject_len;2105 plen = ntohs(pp->prlo.prlo_len);2106 if (plen != 20)2107 goto reject_len;2108 if (plen < len)2109 len = plen;2110 2111 rspp = &pp->spp;2112 2113 fp = fc_frame_alloc(lport, len);2114 if (!fp) {2115 rjt_data.reason = ELS_RJT_UNAB;2116 rjt_data.explan = ELS_EXPL_INSUF_RES;2117 goto reject;2118 }2119 2120 pp = fc_frame_payload_get(fp, len);2121 WARN_ON(!pp);2122 memset(pp, 0, len);2123 pp->prlo.prlo_cmd = ELS_LS_ACC;2124 pp->prlo.prlo_obs = 0x10;2125 pp->prlo.prlo_len = htons(len);2126 spp = &pp->spp;2127 spp->spp_type = rspp->spp_type;2128 spp->spp_type_ext = rspp->spp_type_ext;2129 spp->spp_flags = FC_SPP_RESP_ACK;2130 2131 fc_rport_enter_prli(rdata);2132 2133 fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);2134 lport->tt.frame_send(lport, fp);2135 goto drop;2136 2137reject_len:2138 rjt_data.reason = ELS_RJT_PROT;2139 rjt_data.explan = ELS_EXPL_INV_LEN;2140reject:2141 fc_seq_els_rsp_send(rx_fp, ELS_LS_RJT, &rjt_data);2142drop:2143 fc_frame_free(rx_fp);2144}2145 2146/**2147 * fc_rport_recv_logo_req() - Handler for logout (LOGO) requests2148 * @lport: The local port that received the LOGO request2149 * @fp: The LOGO request frame2150 *2151 * Reference counting: drops kref on return2152 */2153static void fc_rport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)2154{2155 struct fc_rport_priv *rdata;2156 u32 sid;2157 2158 lockdep_assert_held(&lport->lp_mutex);2159 2160 fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);2161 2162 sid = fc_frame_sid(fp);2163 2164 rdata = fc_rport_lookup(lport, sid);2165 if (rdata) {2166 mutex_lock(&rdata->rp_mutex);2167 FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",2168 fc_rport_state(rdata));2169 2170 fc_rport_enter_delete(rdata, RPORT_EV_STOP);2171 mutex_unlock(&rdata->rp_mutex);2172 kref_put(&rdata->kref, fc_rport_destroy);2173 } else2174 FC_RPORT_ID_DBG(lport, sid,2175 "Received LOGO from non-logged-in port\n");2176 fc_frame_free(fp);2177}2178 2179/**2180 * fc_rport_flush_queue() - Flush the rport_event_queue2181 */2182void fc_rport_flush_queue(void)2183{2184 flush_workqueue(rport_event_queue);2185}2186EXPORT_SYMBOL(fc_rport_flush_queue);2187 2188/**2189 * fc_rport_fcp_prli() - Handle incoming PRLI for the FCP initiator.2190 * @rdata: remote port private2191 * @spp_len: service parameter page length2192 * @rspp: received service parameter page2193 * @spp: response service parameter page2194 *2195 * Returns the value for the response code to be placed in spp_flags;2196 * Returns 0 if not an initiator.2197 */2198static int fc_rport_fcp_prli(struct fc_rport_priv *rdata, u32 spp_len,2199 const struct fc_els_spp *rspp,2200 struct fc_els_spp *spp)2201{2202 struct fc_lport *lport = rdata->local_port;2203 u32 fcp_parm;2204 2205 fcp_parm = ntohl(rspp->spp_params);2206 rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;2207 if (fcp_parm & FCP_SPPF_INIT_FCN)2208 rdata->ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;2209 if (fcp_parm & FCP_SPPF_TARG_FCN)2210 rdata->ids.roles |= FC_RPORT_ROLE_FCP_TARGET;2211 if (fcp_parm & FCP_SPPF_RETRY)2212 rdata->flags |= FC_RP_FLAGS_RETRY;2213 rdata->supported_classes = FC_COS_CLASS3;2214 2215 if (!(lport->service_params & FCP_SPPF_INIT_FCN))2216 return 0;2217 2218 spp->spp_flags |= rspp->spp_flags & FC_SPP_EST_IMG_PAIR;2219 2220 /*2221 * OR in our service parameters with other providers (target), if any.2222 */2223 fcp_parm = ntohl(spp->spp_params);2224 spp->spp_params = htonl(fcp_parm | lport->service_params);2225 return FC_SPP_RESP_ACK;2226}2227 2228/*2229 * FC-4 provider ops for FCP initiator.2230 */2231struct fc4_prov fc_rport_fcp_init = {2232 .prli = fc_rport_fcp_prli,2233};2234 2235/**2236 * fc_rport_t0_prli() - Handle incoming PRLI parameters for type 02237 * @rdata: remote port private2238 * @spp_len: service parameter page length2239 * @rspp: received service parameter page2240 * @spp: response service parameter page2241 */2242static int fc_rport_t0_prli(struct fc_rport_priv *rdata, u32 spp_len,2243 const struct fc_els_spp *rspp,2244 struct fc_els_spp *spp)2245{2246 if (rspp->spp_flags & FC_SPP_EST_IMG_PAIR)2247 return FC_SPP_RESP_INVL;2248 return FC_SPP_RESP_ACK;2249}2250 2251/*2252 * FC-4 provider ops for type 0 service parameters.2253 *2254 * This handles the special case of type 0 which is always successful2255 * but doesn't do anything otherwise.2256 */2257struct fc4_prov fc_rport_t0_prov = {2258 .prli = fc_rport_t0_prli,2259};2260 2261/**2262 * fc_setup_rport() - Initialize the rport_event_queue2263 */2264int fc_setup_rport(void)2265{2266 rport_event_queue =2267 alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, "fc_rport_eq");2268 if (!rport_event_queue)2269 return -ENOMEM;2270 return 0;2271}2272 2273/**2274 * fc_destroy_rport() - Destroy the rport_event_queue2275 */2276void fc_destroy_rport(void)2277{2278 destroy_workqueue(rport_event_queue);2279}2280 2281/**2282 * fc_rport_terminate_io() - Stop all outstanding I/O on a remote port2283 * @rport: The remote port whose I/O should be terminated2284 */2285void fc_rport_terminate_io(struct fc_rport *rport)2286{2287 struct fc_rport_libfc_priv *rpriv = rport->dd_data;2288 struct fc_lport *lport = rpriv->local_port;2289 2290 lport->tt.exch_mgr_reset(lport, 0, rport->port_id);2291 lport->tt.exch_mgr_reset(lport, rport->port_id, 0);2292}2293EXPORT_SYMBOL(fc_rport_terminate_io);2294