92 #include <linux/module.h>
93 #include <linux/slab.h>
94 #include <asm/unaligned.h>
105 #define FC_LOCAL_PTP_FID_LO 0x010101
106 #define FC_LOCAL_PTP_FID_HI 0x010102
112 static void fc_lport_enter_reset(
struct fc_lport *);
113 static void fc_lport_enter_flogi(
struct fc_lport *);
114 static void fc_lport_enter_dns(
struct fc_lport *);
116 static void fc_lport_enter_scr(
struct fc_lport *);
117 static void fc_lport_enter_ready(
struct fc_lport *);
118 static void fc_lport_enter_logo(
struct fc_lport *);
122 static const char *fc_lport_state_names[] = {
184 FC_LPORT_DBG(lport,
"Received a %d event for port (%6.6x)\n", event,
198 "on port (%6.6x) for the directory "
199 "server, but the lport is not "
200 "in the DNS or FDMI state, it's in the "
201 "%d state", rdata->
ids.port_id,
203 lport->
tt.rport_logoff(rdata);
228 cp = fc_lport_state_names[lport->
state];
241 static void fc_lport_ptp_setup(
struct fc_lport *lport,
242 u32 remote_fid,
u64 remote_wwpn,
248 kref_put(&lport->
ptp_rdata->kref, lport->
tt.rport_destroy);
250 lport->
ptp_rdata = lport->
tt.rport_create(lport, remote_fid);
252 lport->
ptp_rdata->ids.port_name = remote_wwpn;
253 lport->
ptp_rdata->ids.node_name = remote_wwnn;
258 fc_lport_enter_ready(lport);
267 struct fc_lport *lport = shost_priv(shost);
273 switch (lport->
state) {
290 struct fc_lport *lport = shost_priv(shost);
303 struct fc_lport *lport = shost_priv(shost);
306 u64 fcp_in_bytes = 0;
307 u64 fcp_out_bytes = 0;
317 struct fc_stats *
stats;
359 static void fc_lport_flogi_fill(
struct fc_lport *lport,
366 memset(flogi, 0,
sizeof(*flogi));
379 sp->sp_tot_seq =
htons(255);
380 sp->sp_rel_off =
htons(0x1f);
412 FC_LPORT_DBG(lport,
"Received RLIR request while in state %s\n",
427 static void fc_lport_recv_echo_req(
struct fc_lport *lport,
435 FC_LPORT_DBG(lport,
"Received ECHO request while in state %s\n",
439 pp = fc_frame_payload_get(in_fp, len);
444 fp = fc_frame_alloc(lport, len);
446 dp = fc_frame_payload_get(fp, len);
450 lport->
tt.frame_send(lport, fp);
452 fc_frame_free(in_fp);
463 static void fc_lport_recv_rnid_req(
struct fc_lport *lport,
477 FC_LPORT_DBG(lport,
"Received RNID request while in state %s\n",
480 req = fc_frame_payload_get(in_fp,
sizeof(*req));
484 lport->
tt.seq_els_rsp_send(in_fp,
ELS_LS_RJT, &rjt_data);
491 len -=
sizeof(
rp->gen);
493 fp = fc_frame_alloc(lport, len);
495 rp = fc_frame_payload_get(fp, len);
498 rp->rnid.rnid_fmt =
fmt;
499 rp->rnid.rnid_cid_len =
sizeof(
rp->cid);
503 rp->rnid.rnid_sid_len =
sizeof(
rp->gen);
508 lport->
tt.frame_send(lport, fp);
511 fc_frame_free(in_fp);
522 static void fc_lport_recv_logo_req(
struct fc_lport *lport,
struct fc_frame *fp)
525 fc_lport_enter_reset(lport);
544 fc_lport_enter_reset(lport);
565 fc_lport_enter_flogi(lport);
594 fc_lport_enter_reset(lport);
595 lport->
tt.fcp_cleanup(lport);
623 lport->
tt.disc_stop_final(lport);
628 lport->
tt.rport_flush_queue();
630 fc_lport_enter_logo(lport);
652 lport->
tt.frame_send = fc_frame_drop;
655 lport->
tt.fcp_abort_io(lport);
656 lport->
tt.disc_stop_final(lport);
657 lport->
tt.exch_mgr_reset(lport, 0, 0);
671 unsigned int old_mfs;
676 old_mfs = lport->
mfs;
687 if (!rc && mfs < old_mfs)
688 fc_lport_enter_reset(lport);
701 static void fc_lport_disc_callback(
struct fc_lport *lport,
710 "Discovery failed for port (%6.6x)\n",
713 fc_lport_enter_reset(lport);
729 static void fc_lport_enter_ready(
struct fc_lport *lport)
740 lport->
tt.disc_start(fc_lport_disc_callback, lport);
757 lport->
host->host_no, port_id);
764 if (lport->
tt.lport_set_port_id)
765 lport->
tt.lport_set_port_id(lport, port_id, fp);
781 fc_lport_set_port_id(lport, port_id,
NULL);
783 switch (lport->
state) {
787 fc_lport_enter_ready(lport);
808 static void fc_lport_recv_flogi_req(
struct fc_lport *lport,
819 FC_LPORT_DBG(lport,
"Received FLOGI request while in state %s\n",
822 remote_fid = fc_frame_sid(rx_fp);
823 flp = fc_frame_payload_get(rx_fp,
sizeof(*flp));
827 if (remote_wwpn == lport->
wwpn) {
829 "with same WWPN %16.16llx\n",
830 lport->
host->host_no, remote_wwpn);
833 FC_LPORT_DBG(lport,
"FLOGI from port WWPN %16.16llx\n", remote_wwpn);
841 if (remote_wwpn < lport->
wwpn) {
843 if (!remote_fid || remote_fid == local_fid)
845 }
else if (!remote_fid) {
849 fc_lport_set_port_id(lport, local_fid, rx_fp);
851 fp = fc_frame_alloc(lport,
sizeof(*flp));
853 new_flp = fc_frame_payload_get(fp,
sizeof(*flp));
854 fc_lport_flogi_fill(lport, new_flp,
ELS_FLOGI);
862 fh = fc_frame_header_get(fp);
865 lport->
tt.frame_send(lport, fp);
868 fc_lport_error(lport, fp);
870 fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
873 fc_frame_free(rx_fp);
887 static void fc_lport_recv_els_req(
struct fc_lport *lport,
905 recv = lport->
tt.rport_recv_req;
906 switch (fc_frame_payload_op(fp)) {
909 recv = fc_lport_recv_flogi_req;
913 recv = fc_lport_recv_logo_req;
916 recv = lport->
tt.disc_recv_req;
919 recv = fc_lport_recv_echo_req;
922 recv = fc_lport_recv_rlir_req;
925 recv = fc_lport_recv_rnid_req;
942 .prli = fc_lport_els_prli,
943 .recv = fc_lport_recv_els_req,
954 static void fc_lport_recv_req(
struct fc_lport *lport,
973 if (!prov || !try_module_get(prov->
module))
976 prov->
recv(lport, fp);
984 lport->
tt.exch_done(sp);
998 fc_lport_enter_reset(lport);
1011 static void fc_lport_reset_locked(
struct fc_lport *lport)
1018 kref_put(&lport->
ptp_rdata->kref, lport->
tt.rport_destroy);
1022 lport->
tt.disc_stop(lport);
1024 lport->
tt.exch_mgr_reset(lport, 0, 0);
1028 fc_lport_set_port_id(lport, 0,
NULL);
1038 static void fc_lport_enter_reset(
struct fc_lport *lport)
1040 FC_LPORT_DBG(lport,
"Entered RESET state from %s state\n",
1056 fc_lport_reset_locked(lport);
1058 fc_lport_enter_flogi(lport);
1068 static void fc_lport_enter_disabled(
struct fc_lport *lport)
1070 FC_LPORT_DBG(lport,
"Entered disabled state from %s state\n",
1075 fc_lport_reset_locked(lport);
1089 unsigned long delay = 0;
1090 FC_LPORT_DBG(lport,
"Error %ld in state %s, retries %d\n",
1111 fc_lport_enter_reset(lport);
1125 static void fc_lport_ns_resp(
struct fc_seq *sp,
struct fc_frame *fp,
1140 FC_LPORT_DBG(lport,
"Received a name server response, "
1148 fc_lport_error(lport, fp);
1152 fh = fc_frame_header_get(fp);
1153 ct = fc_frame_payload_get(fp,
sizeof(*ct));
1159 switch (lport->
state) {
1174 fc_lport_enter_fdmi(lport);
1176 fc_lport_enter_scr(lport);
1183 fc_lport_error(lport, fp);
1201 static void fc_lport_ms_resp(
struct fc_seq *sp,
struct fc_frame *fp,
1216 FC_LPORT_DBG(lport,
"Received a management server response, "
1224 fc_lport_error(lport, fp);
1228 fh = fc_frame_header_get(fp);
1229 ct = fc_frame_payload_get(fp,
sizeof(*ct));
1234 FC_LPORT_DBG(lport,
"Received a management server response, "
1235 "reason=%d explain=%d\n",
1239 switch (lport->
state) {
1244 fc_lport_enter_scr(lport);
1247 fc_lport_enter_scr(lport);
1261 fc_lport_error(lport, fp);
1279 static void fc_lport_scr_resp(
struct fc_seq *sp,
struct fc_frame *fp,
1293 FC_LPORT_DBG(lport,
"Received a SCR response, but in state "
1301 fc_lport_error(lport, fp);
1305 op = fc_frame_payload_op(fp);
1307 fc_lport_enter_ready(lport);
1309 fc_lport_error(lport, fp);
1324 static void fc_lport_enter_scr(
struct fc_lport *lport)
1328 FC_LPORT_DBG(lport,
"Entered SCR state from %s state\n",
1333 fp = fc_frame_alloc(lport,
sizeof(
struct fc_els_scr));
1335 fc_lport_error(lport, fp);
1340 fc_lport_scr_resp, lport,
1342 fc_lport_error(lport,
NULL);
1359 FC_LPORT_DBG(lport,
"Entered %s state from %s state\n",
1360 fc_lport_state_names[state],
1363 fc_lport_state_enter(lport, state);
1395 fc_lport_error(lport,
NULL);
1399 fp = fc_frame_alloc(lport, size);
1401 fc_lport_error(lport, fp);
1408 fc_lport_error(lport, fp);
1412 .event_callback = fc_lport_rport_callback,
1422 static void fc_lport_enter_dns(
struct fc_lport *lport)
1426 FC_LPORT_DBG(lport,
"Entered DNS state from %s state\n",
1437 rdata->
ops = &fc_lport_rport_ops;
1438 lport->
tt.rport_login(rdata);
1442 fc_lport_error(lport,
NULL);
1460 FC_LPORT_DBG(lport,
"Entered %s state from %s state\n",
1461 fc_lport_state_names[state],
1464 fc_lport_state_enter(lport, state);
1514 fc_lport_error(lport,
NULL);
1519 cmd, (
int)len, size);
1520 fp = fc_frame_alloc(lport, size);
1522 fc_lport_error(lport, fp);
1529 fc_lport_error(lport, fp);
1539 static void fc_lport_enter_fdmi(
struct fc_lport *lport)
1543 FC_LPORT_DBG(lport,
"Entered FDMI state from %s state\n",
1554 rdata->
ops = &fc_lport_rport_ops;
1555 lport->
tt.rport_login(rdata);
1559 fc_lport_error(lport,
NULL);
1574 switch (lport->
state) {
1582 fc_lport_enter_flogi(lport);
1585 fc_lport_enter_dns(lport);
1592 fc_lport_enter_ns(lport, lport->
state);
1595 fc_lport_enter_fdmi(lport);
1601 FC_LPORT_DBG(lport,
"Skipping lport state %s to SCR\n",
1605 fc_lport_enter_scr(lport);
1608 fc_lport_enter_logo(lport);
1639 FC_LPORT_DBG(lport,
"Received a LOGO response, but in state "
1647 fc_lport_error(lport, fp);
1651 op = fc_frame_payload_op(fp);
1653 fc_lport_enter_disabled(lport);
1655 fc_lport_error(lport, fp);
1671 static void fc_lport_enter_logo(
struct fc_lport *lport)
1676 FC_LPORT_DBG(lport,
"Entered LOGO state from %s state\n",
1682 fp = fc_frame_alloc(lport,
sizeof(*logo));
1684 fc_lport_error(lport, fp);
1691 fc_lport_error(lport,
NULL);
1712 unsigned int r_a_tov;
1713 unsigned int e_d_tov;
1724 FC_LPORT_DBG(lport,
"Received a FLOGI response, but in state "
1732 fc_lport_error(lport, fp);
1736 fh = fc_frame_header_get(fp);
1737 did = fc_frame_did(fp);
1740 FC_LPORT_DBG(lport,
"FLOGI not accepted or bad response\n");
1741 fc_lport_error(lport, fp);
1745 flp = fc_frame_payload_get(fp,
sizeof(*flp));
1748 fc_lport_error(lport, fp);
1757 "lport->mfs:%hu\n", mfs, lport->
mfs);
1758 fc_lport_error(lport, fp);
1762 if (mfs <= lport->mfs) {
1779 fc_lport_set_port_id(lport, did, fp);
1781 "Port (%6.6x) entered "
1782 "point-to-point mode\n",
1783 lport->
host->host_no, did);
1784 fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1794 fc_lport_set_port_id(lport, did, fp);
1795 fc_lport_enter_dns(lport);
1812 static void fc_lport_enter_flogi(
struct fc_lport *lport)
1816 FC_LPORT_DBG(lport,
"Entered FLOGI state from %s state\n",
1823 fc_lport_enter_ready(lport);
1827 fp = fc_frame_alloc(lport,
sizeof(
struct fc_els_flogi));
1829 return fc_lport_error(lport, fp);
1836 fc_lport_error(lport,
NULL);
1864 if (!lport->
tt.lport_recv)
1865 lport->
tt.lport_recv = fc_lport_recv_req;
1867 if (!lport->
tt.lport_reset)
1902 static void fc_lport_bsg_resp(
struct fc_seq *sp,
struct fc_frame *fp,
1923 fh = fc_frame_header_get(fp);
1924 len =
fr_len(fp) -
sizeof(*fh);
1925 buf = fc_frame_payload_get(fp, 0);
1931 (
unsigned short)fc_frame_payload_op(fp);
1934 job->
reply->reply_data.ctels_reply.status =
1939 job->
reply->reply_payload_rcv_len +=
1946 if (job->
reply->reply_payload_rcv_len >
1948 job->
reply->reply_payload_rcv_len =
1950 job->
reply->result = 0;
1968 static int fc_lport_els_request(
struct fc_bsg_job *job,
1983 pp = fc_frame_payload_get(fp, len);
1989 fh = fc_frame_header_get(fp);
2011 if (!lport->
tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
2029 static int fc_lport_ct_request(
struct fc_bsg_job *job,
2038 fp = fc_frame_alloc(lport,
sizeof(
struct fc_ct_hdr) +
2044 ct = fc_frame_payload_get(fp, len);
2050 fh = fc_frame_header_get(fp);
2072 if (!lport->
tt.exch_seq_send(lport, fp, fc_lport_bsg_resp,
2089 struct fc_lport *lport = shost_priv(shost);
2095 job->
reply->reply_payload_rcv_len = 0;
2101 switch (job->
request->msgcode) {
2108 rc = fc_lport_els_request(job, lport, rport->
port_id,
2118 rc = fc_lport_ct_request(job, lport, rport->
port_id,
2127 rdata = lport->
tt.rport_lookup(lport, did);
2132 rc = fc_lport_ct_request(job, lport, did, rdata->
e_d_tov);
2137 rc = fc_lport_els_request(job, lport, did, lport->
e_d_tov);