x86/amd-iommu: Add per IOMMU reference counting
[linux/fpc-iii.git] / drivers / scsi / bfa / ms.c
blobc96b3ca007aec0aede127cc8d88ae4c0decb9680
1 /*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 #include <bfa.h>
20 #include <bfa_svc.h>
21 #include "fcs_lport.h"
22 #include "fcs_rport.h"
23 #include "fcs_trcmod.h"
24 #include "fcs_fcxp.h"
25 #include "lport_priv.h"
27 BFA_TRC_FILE(FCS, MS);
29 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
31 * forward declarations
33 static void bfa_fcs_port_ms_send_plogi(void *ms_cbarg,
34 struct bfa_fcxp_s *fcxp_alloced);
35 static void bfa_fcs_port_ms_timeout(void *arg);
36 static void bfa_fcs_port_ms_plogi_response(void *fcsarg,
37 struct bfa_fcxp_s *fcxp,
38 void *cbarg,
39 bfa_status_t req_status,
40 u32 rsp_len,
41 u32 resid_len,
42 struct fchs_s *rsp_fchs);
44 static void bfa_fcs_port_ms_send_gmal(void *ms_cbarg,
45 struct bfa_fcxp_s *fcxp_alloced);
46 static void bfa_fcs_port_ms_gmal_response(void *fcsarg,
47 struct bfa_fcxp_s *fcxp,
48 void *cbarg,
49 bfa_status_t req_status,
50 u32 rsp_len,
51 u32 resid_len,
52 struct fchs_s *rsp_fchs);
53 static void bfa_fcs_port_ms_send_gfn(void *ms_cbarg,
54 struct bfa_fcxp_s *fcxp_alloced);
55 static void bfa_fcs_port_ms_gfn_response(void *fcsarg,
56 struct bfa_fcxp_s *fcxp,
57 void *cbarg,
58 bfa_status_t req_status,
59 u32 rsp_len,
60 u32 resid_len,
61 struct fchs_s *rsp_fchs);
62 /**
63 * fcs_ms_sm FCS MS state machine
66 /**
67 * MS State Machine events
69 enum port_ms_event {
70 MSSM_EVENT_PORT_ONLINE = 1,
71 MSSM_EVENT_PORT_OFFLINE = 2,
72 MSSM_EVENT_RSP_OK = 3,
73 MSSM_EVENT_RSP_ERROR = 4,
74 MSSM_EVENT_TIMEOUT = 5,
75 MSSM_EVENT_FCXP_SENT = 6,
76 MSSM_EVENT_PORT_FABRIC_RSCN = 7
79 static void bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
80 enum port_ms_event event);
81 static void bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
82 enum port_ms_event event);
83 static void bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms,
84 enum port_ms_event event);
85 static void bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
86 enum port_ms_event event);
87 static void bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
88 enum port_ms_event event);
89 static void bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms,
90 enum port_ms_event event);
91 static void bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
92 enum port_ms_event event);
93 static void bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
94 enum port_ms_event event);
95 static void bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms,
96 enum port_ms_event event);
97 static void bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
98 enum port_ms_event event);
99 static void bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
100 enum port_ms_event event);
102 * Start in offline state - awaiting NS to send start.
104 static void
105 bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
106 enum port_ms_event event)
108 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
109 bfa_trc(ms->port->fcs, event);
111 switch (event) {
112 case MSSM_EVENT_PORT_ONLINE:
113 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
114 bfa_fcs_port_ms_send_plogi(ms, NULL);
115 break;
117 case MSSM_EVENT_PORT_OFFLINE:
118 break;
120 default:
121 bfa_assert(0);
125 static void
126 bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
127 enum port_ms_event event)
129 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
130 bfa_trc(ms->port->fcs, event);
132 switch (event) {
133 case MSSM_EVENT_FCXP_SENT:
134 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi);
135 break;
137 case MSSM_EVENT_PORT_OFFLINE:
138 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
139 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
140 &ms->fcxp_wqe);
141 break;
143 default:
144 bfa_assert(0);
148 static void
149 bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
151 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
152 bfa_trc(ms->port->fcs, event);
154 switch (event) {
155 case MSSM_EVENT_RSP_ERROR:
157 * Start timer for a delayed retry
159 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_retry);
160 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), &ms->timer,
161 bfa_fcs_port_ms_timeout, ms,
162 BFA_FCS_RETRY_TIMEOUT);
163 break;
165 case MSSM_EVENT_RSP_OK:
167 * since plogi is done, now invoke MS related sub-modules
169 bfa_fcs_port_fdmi_online(ms);
172 * if this is a Vport, go to online state.
174 if (ms->port->vport) {
175 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
176 break;
180 * For a base port we need to get the
181 * switch's IP address.
183 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
184 bfa_fcs_port_ms_send_gmal(ms, NULL);
185 break;
187 case MSSM_EVENT_PORT_OFFLINE:
188 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
189 bfa_fcxp_discard(ms->fcxp);
190 break;
192 default:
193 bfa_assert(0);
197 static void
198 bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
199 enum port_ms_event event)
201 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
202 bfa_trc(ms->port->fcs, event);
204 switch (event) {
205 case MSSM_EVENT_TIMEOUT:
207 * Retry Timer Expired. Re-send
209 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
210 bfa_fcs_port_ms_send_plogi(ms, NULL);
211 break;
213 case MSSM_EVENT_PORT_OFFLINE:
214 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
215 bfa_timer_stop(&ms->timer);
216 break;
218 default:
219 bfa_assert(0);
223 static void
224 bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
225 enum port_ms_event event)
227 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
228 bfa_trc(ms->port->fcs, event);
230 switch (event) {
231 case MSSM_EVENT_PORT_OFFLINE:
232 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
234 * now invoke MS related sub-modules
236 bfa_fcs_port_fdmi_offline(ms);
237 break;
239 case MSSM_EVENT_PORT_FABRIC_RSCN:
240 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
241 ms->retry_cnt = 0;
242 bfa_fcs_port_ms_send_gfn(ms, NULL);
243 break;
245 default:
246 bfa_assert(0);
250 static void
251 bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
252 enum port_ms_event event)
254 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
255 bfa_trc(ms->port->fcs, event);
257 switch (event) {
258 case MSSM_EVENT_FCXP_SENT:
259 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal);
260 break;
262 case MSSM_EVENT_PORT_OFFLINE:
263 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
264 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
265 &ms->fcxp_wqe);
266 break;
268 default:
269 bfa_assert(0);
273 static void
274 bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
276 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
277 bfa_trc(ms->port->fcs, event);
279 switch (event) {
280 case MSSM_EVENT_RSP_ERROR:
282 * Start timer for a delayed retry
284 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
285 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry);
286 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
287 &ms->timer, bfa_fcs_port_ms_timeout, ms,
288 BFA_FCS_RETRY_TIMEOUT);
289 } else {
290 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
291 bfa_fcs_port_ms_send_gfn(ms, NULL);
292 ms->retry_cnt = 0;
294 break;
296 case MSSM_EVENT_RSP_OK:
297 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
298 bfa_fcs_port_ms_send_gfn(ms, NULL);
299 break;
301 case MSSM_EVENT_PORT_OFFLINE:
302 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
303 bfa_fcxp_discard(ms->fcxp);
304 break;
306 default:
307 bfa_assert(0);
311 static void
312 bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
313 enum port_ms_event event)
315 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
316 bfa_trc(ms->port->fcs, event);
318 switch (event) {
319 case MSSM_EVENT_TIMEOUT:
321 * Retry Timer Expired. Re-send
323 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
324 bfa_fcs_port_ms_send_gmal(ms, NULL);
325 break;
327 case MSSM_EVENT_PORT_OFFLINE:
328 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
329 bfa_timer_stop(&ms->timer);
330 break;
332 default:
333 bfa_assert(0);
338 * ms_pvt MS local functions
341 static void
342 bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
344 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
345 struct bfa_fcs_port_s *port = ms->port;
346 struct fchs_s fchs;
347 int len;
348 struct bfa_fcxp_s *fcxp;
350 bfa_trc(port->fcs, port->pid);
352 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
353 if (!fcxp) {
354 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
355 bfa_fcs_port_ms_send_gmal, ms);
356 return;
358 ms->fcxp = fcxp;
360 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
361 bfa_fcs_port_get_fcid(port),
362 bfa_lps_get_peer_nwwn(port->fabric->lps));
364 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
365 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response,
366 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
368 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
371 static void
372 bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
373 void *cbarg, bfa_status_t req_status,
374 u32 rsp_len, u32 resid_len,
375 struct fchs_s *rsp_fchs)
377 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
378 struct bfa_fcs_port_s *port = ms->port;
379 struct ct_hdr_s *cthdr = NULL;
380 struct fcgs_gmal_resp_s *gmal_resp;
381 struct fc_gmal_entry_s *gmal_entry;
382 u32 num_entries;
383 u8 *rsp_str;
385 bfa_trc(port->fcs, req_status);
386 bfa_trc(port->fcs, port->port_cfg.pwwn);
389 * Sanity Checks
391 if (req_status != BFA_STATUS_OK) {
392 bfa_trc(port->fcs, req_status);
393 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
394 return;
397 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
398 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
400 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
401 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
402 num_entries = bfa_os_ntohl(gmal_resp->ms_len);
403 if (num_entries == 0) {
404 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
405 return;
408 * The response could contain multiple Entries.
409 * Entries for SNMP interface, etc.
410 * We look for the entry with a telnet prefix.
411 * First "http://" entry refers to IP addr
414 gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma;
415 while (num_entries > 0) {
416 if (strncmp
417 (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP,
418 sizeof(gmal_entry->prefix)) == 0) {
421 * if the IP address is terminating with a '/',
422 * remove it. *Byte 0 consists of the length
423 * of the string.
425 rsp_str = &(gmal_entry->prefix[0]);
426 if (rsp_str[gmal_entry->len - 1] == '/')
427 rsp_str[gmal_entry->len - 1] = 0;
429 * copy IP Address to fabric
431 strncpy(bfa_fcs_port_get_fabric_ipaddr(port),
432 gmal_entry->ip_addr,
433 BFA_FCS_FABRIC_IPADDR_SZ);
434 break;
435 } else {
436 --num_entries;
437 ++gmal_entry;
441 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
442 return;
445 bfa_trc(port->fcs, cthdr->reason_code);
446 bfa_trc(port->fcs, cthdr->exp_code);
447 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
450 static void
451 bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
452 enum port_ms_event event)
454 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
455 bfa_trc(ms->port->fcs, event);
457 switch (event) {
458 case MSSM_EVENT_FCXP_SENT:
459 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn);
460 break;
462 case MSSM_EVENT_PORT_OFFLINE:
463 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
464 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
465 &ms->fcxp_wqe);
466 break;
468 default:
469 bfa_assert(0);
473 static void
474 bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
476 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
477 bfa_trc(ms->port->fcs, event);
479 switch (event) {
480 case MSSM_EVENT_RSP_ERROR:
482 * Start timer for a delayed retry
484 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
485 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry);
486 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
487 &ms->timer, bfa_fcs_port_ms_timeout, ms,
488 BFA_FCS_RETRY_TIMEOUT);
489 } else {
490 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
491 ms->retry_cnt = 0;
493 break;
495 case MSSM_EVENT_RSP_OK:
496 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
497 break;
499 case MSSM_EVENT_PORT_OFFLINE:
500 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
501 bfa_fcxp_discard(ms->fcxp);
502 break;
504 default:
505 bfa_assert(0);
509 static void
510 bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
511 enum port_ms_event event)
513 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
514 bfa_trc(ms->port->fcs, event);
516 switch (event) {
517 case MSSM_EVENT_TIMEOUT:
519 * Retry Timer Expired. Re-send
521 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
522 bfa_fcs_port_ms_send_gfn(ms, NULL);
523 break;
525 case MSSM_EVENT_PORT_OFFLINE:
526 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
527 bfa_timer_stop(&ms->timer);
528 break;
530 default:
531 bfa_assert(0);
536 * ms_pvt MS local functions
539 static void
540 bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
542 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
543 struct bfa_fcs_port_s *port = ms->port;
544 struct fchs_s fchs;
545 int len;
546 struct bfa_fcxp_s *fcxp;
548 bfa_trc(port->fcs, port->pid);
550 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
551 if (!fcxp) {
552 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
553 bfa_fcs_port_ms_send_gfn, ms);
554 return;
556 ms->fcxp = fcxp;
558 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
559 bfa_fcs_port_get_fcid(port),
560 bfa_lps_get_peer_nwwn(port->fabric->lps));
562 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
563 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response,
564 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
566 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
569 static void
570 bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
571 bfa_status_t req_status, u32 rsp_len,
572 u32 resid_len, struct fchs_s *rsp_fchs)
574 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
575 struct bfa_fcs_port_s *port = ms->port;
576 struct ct_hdr_s *cthdr = NULL;
577 wwn_t *gfn_resp;
579 bfa_trc(port->fcs, req_status);
580 bfa_trc(port->fcs, port->port_cfg.pwwn);
583 * Sanity Checks
585 if (req_status != BFA_STATUS_OK) {
586 bfa_trc(port->fcs, req_status);
587 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
588 return;
591 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
592 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
594 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
595 gfn_resp = (wwn_t *) (cthdr + 1);
597 * check if it has actually changed
599 if ((memcmp
600 ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp,
601 sizeof(wwn_t)) != 0))
602 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
603 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
604 return;
607 bfa_trc(port->fcs, cthdr->reason_code);
608 bfa_trc(port->fcs, cthdr->exp_code);
609 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
613 * ms_pvt MS local functions
616 static void
617 bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
619 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
620 struct bfa_fcs_port_s *port = ms->port;
621 struct fchs_s fchs;
622 int len;
623 struct bfa_fcxp_s *fcxp;
625 bfa_trc(port->fcs, port->pid);
627 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
628 if (!fcxp) {
629 port->stats.ms_plogi_alloc_wait++;
630 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
631 bfa_fcs_port_ms_send_plogi, ms);
632 return;
634 ms->fcxp = fcxp;
636 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
637 bfa_os_hton3b(FC_MGMT_SERVER),
638 bfa_fcs_port_get_fcid(port), 0,
639 port->port_cfg.pwwn, port->port_cfg.nwwn,
640 bfa_pport_get_maxfrsize(port->fcs->bfa));
642 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
643 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
644 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
646 port->stats.ms_plogi_sent++;
647 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
650 static void
651 bfa_fcs_port_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
652 void *cbarg, bfa_status_t req_status,
653 u32 rsp_len, u32 resid_len,
654 struct fchs_s *rsp_fchs)
656 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
658 struct bfa_fcs_port_s *port = ms->port;
659 struct fc_els_cmd_s *els_cmd;
660 struct fc_ls_rjt_s *ls_rjt;
662 bfa_trc(port->fcs, req_status);
663 bfa_trc(port->fcs, port->port_cfg.pwwn);
666 * Sanity Checks
668 if (req_status != BFA_STATUS_OK) {
669 port->stats.ms_plogi_rsp_err++;
670 bfa_trc(port->fcs, req_status);
671 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
672 return;
675 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
677 switch (els_cmd->els_code) {
679 case FC_ELS_ACC:
680 if (rsp_len < sizeof(struct fc_logi_s)) {
681 bfa_trc(port->fcs, rsp_len);
682 port->stats.ms_plogi_acc_err++;
683 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
684 break;
686 port->stats.ms_plogi_accepts++;
687 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
688 break;
690 case FC_ELS_LS_RJT:
691 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
693 bfa_trc(port->fcs, ls_rjt->reason_code);
694 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
696 port->stats.ms_rejects++;
697 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
698 break;
700 default:
701 port->stats.ms_plogi_unknown_rsp++;
702 bfa_trc(port->fcs, els_cmd->els_code);
703 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
707 static void
708 bfa_fcs_port_ms_timeout(void *arg)
710 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)arg;
712 ms->port->stats.ms_timeouts++;
713 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
717 void
718 bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port)
720 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
722 ms->port = port;
723 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
726 * Invoke init routines of sub modules.
728 bfa_fcs_port_fdmi_init(ms);
731 void
732 bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
734 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
736 ms->port = port;
737 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
740 void
741 bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port)
743 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
745 ms->port = port;
746 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
749 void
750 bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port)
752 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
755 * @todo. Handle this only when in Online state
757 if (bfa_sm_cmp_state(ms, bfa_fcs_port_ms_sm_online))
758 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);