2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
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 * port_api.c BFA FCS port
25 #include "fcs_lport.h"
26 #include "fcs_rport.h"
27 #include "lport_priv.h"
28 #include "fcs_trcmod.h"
30 #include <fcs/bfa_fcs_fdmi.h>
32 BFA_TRC_FILE(FCS
, FDMI
);
34 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
37 * forward declarations
39 static void bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg
,
40 struct bfa_fcxp_s
*fcxp_alloced
);
41 static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg
,
42 struct bfa_fcxp_s
*fcxp_alloced
);
43 static void bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg
,
44 struct bfa_fcxp_s
*fcxp_alloced
);
45 static void bfa_fcs_port_fdmi_rhba_response(void *fcsarg
,
46 struct bfa_fcxp_s
*fcxp
,
48 bfa_status_t req_status
,
51 struct fchs_s
*rsp_fchs
);
52 static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg
,
53 struct bfa_fcxp_s
*fcxp
,
55 bfa_status_t req_status
,
58 struct fchs_s
*rsp_fchs
);
59 static void bfa_fcs_port_fdmi_rpa_response(void *fcsarg
,
60 struct bfa_fcxp_s
*fcxp
,
62 bfa_status_t req_status
,
65 struct fchs_s
*rsp_fchs
);
66 static void bfa_fcs_port_fdmi_timeout(void *arg
);
67 static u16
bfa_fcs_port_fdmi_build_rhba_pyld(
68 struct bfa_fcs_port_fdmi_s
*fdmi
, u8
*pyld
);
69 static u16
bfa_fcs_port_fdmi_build_rprt_pyld(
70 struct bfa_fcs_port_fdmi_s
*fdmi
, u8
*pyld
);
71 static u16
bfa_fcs_port_fdmi_build_rpa_pyld(
72 struct bfa_fcs_port_fdmi_s
*fdmi
, u8
*pyld
);
73 static u16
bfa_fcs_port_fdmi_build_portattr_block(
74 struct bfa_fcs_port_fdmi_s
*fdmi
, u8
*pyld
);
75 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
76 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
);
77 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
78 struct bfa_fcs_fdmi_port_attr_s
*port_attr
);
80 * fcs_fdmi_sm FCS FDMI state machine
84 * FDMI State Machine events
86 enum port_fdmi_event
{
87 FDMISM_EVENT_PORT_ONLINE
= 1,
88 FDMISM_EVENT_PORT_OFFLINE
= 2,
89 FDMISM_EVENT_RSP_OK
= 4,
90 FDMISM_EVENT_RSP_ERROR
= 5,
91 FDMISM_EVENT_TIMEOUT
= 6,
92 FDMISM_EVENT_RHBA_SENT
= 7,
93 FDMISM_EVENT_RPRT_SENT
= 8,
94 FDMISM_EVENT_RPA_SENT
= 9,
97 static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s
*fdmi
,
98 enum port_fdmi_event event
);
99 static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s
*fdmi
,
100 enum port_fdmi_event event
);
101 static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s
*fdmi
,
102 enum port_fdmi_event event
);
103 static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
104 enum port_fdmi_event event
);
105 static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s
*fdmi
,
106 enum port_fdmi_event event
);
107 static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s
*fdmi
,
108 enum port_fdmi_event event
);
109 static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
110 enum port_fdmi_event event
);
111 static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s
*fdmi
,
112 enum port_fdmi_event event
);
113 static void bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s
*fdmi
,
114 enum port_fdmi_event event
);
115 static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
116 enum port_fdmi_event event
);
117 static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s
*fdmi
,
118 enum port_fdmi_event event
);
119 static void bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s
*fdmi
,
120 enum port_fdmi_event event
);
123 * Start in offline state - awaiting MS to send start.
126 bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s
*fdmi
,
127 enum port_fdmi_event event
)
129 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
131 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
132 bfa_trc(port
->fcs
, event
);
137 case FDMISM_EVENT_PORT_ONLINE
:
140 * For Vports, register a new port.
142 bfa_sm_set_state(fdmi
,
143 bfa_fcs_port_fdmi_sm_sending_rprt
);
144 bfa_fcs_port_fdmi_send_rprt(fdmi
, NULL
);
147 * For a base port, we should first register the HBA
148 * atribute. The HBA attribute also contains the base
151 bfa_sm_set_state(fdmi
,
152 bfa_fcs_port_fdmi_sm_sending_rhba
);
153 bfa_fcs_port_fdmi_send_rhba(fdmi
, NULL
);
157 case FDMISM_EVENT_PORT_OFFLINE
:
161 bfa_sm_fault(port
->fcs
, event
);
166 bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s
*fdmi
,
167 enum port_fdmi_event event
)
169 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
171 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
172 bfa_trc(port
->fcs
, event
);
175 case FDMISM_EVENT_RHBA_SENT
:
176 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rhba
);
179 case FDMISM_EVENT_PORT_OFFLINE
:
180 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
181 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
186 bfa_sm_fault(port
->fcs
, event
);
191 bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s
*fdmi
,
192 enum port_fdmi_event event
)
194 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
196 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
197 bfa_trc(port
->fcs
, event
);
200 case FDMISM_EVENT_RSP_ERROR
:
202 * if max retries have not been reached, start timer for a
205 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
206 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rhba_retry
);
207 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
208 &fdmi
->timer
, bfa_fcs_port_fdmi_timeout
,
209 fdmi
, BFA_FCS_RETRY_TIMEOUT
);
212 * set state to offline
214 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
218 case FDMISM_EVENT_RSP_OK
:
220 * Initiate Register Port Attributes
222 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rpa
);
224 bfa_fcs_port_fdmi_send_rpa(fdmi
, NULL
);
227 case FDMISM_EVENT_PORT_OFFLINE
:
228 bfa_fcxp_discard(fdmi
->fcxp
);
229 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
233 bfa_sm_fault(port
->fcs
, event
);
238 bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
239 enum port_fdmi_event event
)
241 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
243 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
244 bfa_trc(port
->fcs
, event
);
247 case FDMISM_EVENT_TIMEOUT
:
249 * Retry Timer Expired. Re-send
251 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rhba
);
252 bfa_fcs_port_fdmi_send_rhba(fdmi
, NULL
);
255 case FDMISM_EVENT_PORT_OFFLINE
:
256 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
257 bfa_timer_stop(&fdmi
->timer
);
261 bfa_sm_fault(port
->fcs
, event
);
266 * RPRT : Register Port
269 bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s
*fdmi
,
270 enum port_fdmi_event event
)
272 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
274 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
275 bfa_trc(port
->fcs
, event
);
278 case FDMISM_EVENT_RPRT_SENT
:
279 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rprt
);
282 case FDMISM_EVENT_PORT_OFFLINE
:
283 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
284 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
289 bfa_sm_fault(port
->fcs
, event
);
294 bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s
*fdmi
,
295 enum port_fdmi_event event
)
297 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
299 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
300 bfa_trc(port
->fcs
, event
);
303 case FDMISM_EVENT_RSP_ERROR
:
305 * if max retries have not been reached, start timer for a
308 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
309 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rprt_retry
);
310 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
311 &fdmi
->timer
, bfa_fcs_port_fdmi_timeout
,
312 fdmi
, BFA_FCS_RETRY_TIMEOUT
);
316 * set state to offline
318 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
323 case FDMISM_EVENT_RSP_OK
:
325 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_online
);
328 case FDMISM_EVENT_PORT_OFFLINE
:
329 bfa_fcxp_discard(fdmi
->fcxp
);
330 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
334 bfa_sm_fault(port
->fcs
, event
);
339 bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
340 enum port_fdmi_event event
)
342 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
344 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
345 bfa_trc(port
->fcs
, event
);
348 case FDMISM_EVENT_TIMEOUT
:
350 * Retry Timer Expired. Re-send
352 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rprt
);
353 bfa_fcs_port_fdmi_send_rprt(fdmi
, NULL
);
356 case FDMISM_EVENT_PORT_OFFLINE
:
357 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
358 bfa_timer_stop(&fdmi
->timer
);
362 bfa_sm_fault(port
->fcs
, event
);
367 * Register Port Attributes
370 bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s
*fdmi
,
371 enum port_fdmi_event event
)
373 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
375 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
376 bfa_trc(port
->fcs
, event
);
379 case FDMISM_EVENT_RPA_SENT
:
380 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rpa
);
383 case FDMISM_EVENT_PORT_OFFLINE
:
384 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
385 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
390 bfa_sm_fault(port
->fcs
, event
);
395 bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s
*fdmi
,
396 enum port_fdmi_event event
)
398 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
400 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
401 bfa_trc(port
->fcs
, event
);
404 case FDMISM_EVENT_RSP_ERROR
:
406 * if max retries have not been reached, start timer for a
409 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
410 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rpa_retry
);
411 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
412 &fdmi
->timer
, bfa_fcs_port_fdmi_timeout
,
413 fdmi
, BFA_FCS_RETRY_TIMEOUT
);
416 * set state to offline
418 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
423 case FDMISM_EVENT_RSP_OK
:
424 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_online
);
428 case FDMISM_EVENT_PORT_OFFLINE
:
429 bfa_fcxp_discard(fdmi
->fcxp
);
430 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
434 bfa_sm_fault(port
->fcs
, event
);
439 bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
440 enum port_fdmi_event event
)
442 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
444 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
445 bfa_trc(port
->fcs
, event
);
448 case FDMISM_EVENT_TIMEOUT
:
450 * Retry Timer Expired. Re-send
452 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rpa
);
453 bfa_fcs_port_fdmi_send_rpa(fdmi
, NULL
);
456 case FDMISM_EVENT_PORT_OFFLINE
:
457 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
458 bfa_timer_stop(&fdmi
->timer
);
462 bfa_sm_fault(port
->fcs
, event
);
467 bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s
*fdmi
,
468 enum port_fdmi_event event
)
470 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
472 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
473 bfa_trc(port
->fcs
, event
);
476 case FDMISM_EVENT_PORT_OFFLINE
:
477 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
481 bfa_sm_fault(port
->fcs
, event
);
486 * FDMI is disabled state.
489 bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s
*fdmi
,
490 enum port_fdmi_event event
)
492 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
494 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
495 bfa_trc(port
->fcs
, event
);
497 /* No op State. It can only be enabled at Driver Init. */
501 * RHBA : Register HBA Attributes.
504 bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
506 struct bfa_fcs_port_fdmi_s
*fdmi
= fdmi_cbarg
;
507 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
510 struct bfa_fcxp_s
*fcxp
;
513 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
515 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
517 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
518 bfa_fcs_port_fdmi_send_rhba
, fdmi
);
523 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
524 bfa_os_memset(pyld
, 0, FC_MAX_PDUSZ
);
526 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_port_get_fcid(port
),
529 attr_len
= bfa_fcs_port_fdmi_build_rhba_pyld(fdmi
,
530 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
532 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
533 FC_CLASS_3
, (len
+ attr_len
), &fchs
,
534 bfa_fcs_port_fdmi_rhba_response
, (void *)fdmi
,
535 FC_MAX_PDUSZ
, FC_RA_TOV
);
537 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RHBA_SENT
);
541 bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s
*fdmi
,
544 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
545 struct bfa_fcs_fdmi_hba_attr_s hba_attr
; /* @todo */
546 struct bfa_fcs_fdmi_hba_attr_s
*fcs_hba_attr
= &hba_attr
; /* @todo */
547 struct fdmi_rhba_s
*rhba
= (struct fdmi_rhba_s
*) pyld
;
548 struct fdmi_attr_s
*attr
;
555 bfa_fcs_fdmi_get_hbaattr(fdmi
, fcs_hba_attr
);
557 rhba
->hba_id
= bfa_fcs_port_get_pwwn(port
);
558 rhba
->port_list
.num_ports
= bfa_os_htonl(1);
559 rhba
->port_list
.port_entry
= bfa_fcs_port_get_pwwn(port
);
561 len
= sizeof(rhba
->hba_id
) + sizeof(rhba
->port_list
);
564 len
+= sizeof(rhba
->hba_attr_blk
.attr_count
);
567 * fill out the invididual entries of the HBA attrib Block
569 curr_ptr
= (u8
*) &rhba
->hba_attr_blk
.hba_attr
;
574 attr
= (struct fdmi_attr_s
*) curr_ptr
;
575 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME
);
576 attr
->len
= sizeof(wwn_t
);
577 memcpy(attr
->value
, &bfa_fcs_port_get_nwwn(port
), attr
->len
);
578 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
582 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
588 attr
= (struct fdmi_attr_s
*) curr_ptr
;
589 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER
);
590 attr
->len
= (u16
) strlen(fcs_hba_attr
->manufacturer
);
591 memcpy(attr
->value
, fcs_hba_attr
->manufacturer
, attr
->len
);
592 /* variable fields need to be 4 byte aligned */
593 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
594 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
598 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
604 attr
= (struct fdmi_attr_s
*) curr_ptr
;
605 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM
);
606 attr
->len
= (u16
) strlen(fcs_hba_attr
->serial_num
);
607 memcpy(attr
->value
, fcs_hba_attr
->serial_num
, attr
->len
);
608 /* variable fields need to be 4 byte aligned */
609 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
610 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
614 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
620 attr
= (struct fdmi_attr_s
*) curr_ptr
;
621 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MODEL
);
622 attr
->len
= (u16
) strlen(fcs_hba_attr
->model
);
623 memcpy(attr
->value
, fcs_hba_attr
->model
, attr
->len
);
624 /* variable fields need to be 4 byte aligned */
625 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
626 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
630 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
636 attr
= (struct fdmi_attr_s
*) curr_ptr
;
637 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC
);
638 attr
->len
= (u16
) strlen(fcs_hba_attr
->model_desc
);
639 memcpy(attr
->value
, fcs_hba_attr
->model_desc
, attr
->len
);
640 /* variable fields need to be 4 byte aligned */
641 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
642 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
646 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
652 if (fcs_hba_attr
->hw_version
[0] != '\0') {
653 attr
= (struct fdmi_attr_s
*) curr_ptr
;
654 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION
);
655 attr
->len
= (u16
) strlen(fcs_hba_attr
->hw_version
);
656 memcpy(attr
->value
, fcs_hba_attr
->hw_version
, attr
->len
);
657 /* variable fields need to be 4 byte aligned */
658 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
659 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
663 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
670 attr
= (struct fdmi_attr_s
*) curr_ptr
;
671 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION
);
672 attr
->len
= (u16
) strlen(fcs_hba_attr
->driver_version
);
673 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, attr
->len
);
674 /* variable fields need to be 4 byte aligned */
675 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
676 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
680 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
686 if (fcs_hba_attr
->option_rom_ver
[0] != '\0') {
687 attr
= (struct fdmi_attr_s
*) curr_ptr
;
688 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION
);
689 attr
->len
= (u16
) strlen(fcs_hba_attr
->option_rom_ver
);
690 memcpy(attr
->value
, fcs_hba_attr
->option_rom_ver
, attr
->len
);
691 /* variable fields need to be 4 byte aligned */
692 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
693 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
697 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
702 * f/w Version = driver version
704 attr
= (struct fdmi_attr_s
*) curr_ptr
;
705 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION
);
706 attr
->len
= (u16
) strlen(fcs_hba_attr
->driver_version
);
707 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, attr
->len
);
708 /* variable fields need to be 4 byte aligned */
709 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
710 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
714 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
720 if (fcs_hba_attr
->os_name
[0] != '\0') {
721 attr
= (struct fdmi_attr_s
*) curr_ptr
;
722 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME
);
723 attr
->len
= (u16
) strlen(fcs_hba_attr
->os_name
);
724 memcpy(attr
->value
, fcs_hba_attr
->os_name
, attr
->len
);
725 /* variable fields need to be 4 byte aligned */
726 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
727 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
731 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
738 attr
= (struct fdmi_attr_s
*) curr_ptr
;
739 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT
);
740 attr
->len
= sizeof(fcs_hba_attr
->max_ct_pyld
);
741 memcpy(attr
->value
, &fcs_hba_attr
->max_ct_pyld
, attr
->len
);
745 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
749 * Update size of payload
751 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
753 rhba
->hba_attr_blk
.attr_count
= bfa_os_htonl(count
);
758 bfa_fcs_port_fdmi_rhba_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
759 void *cbarg
, bfa_status_t req_status
,
760 u32 rsp_len
, u32 resid_len
,
761 struct fchs_s
*rsp_fchs
)
763 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)cbarg
;
764 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
765 struct ct_hdr_s
*cthdr
= NULL
;
767 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
772 if (req_status
!= BFA_STATUS_OK
) {
773 bfa_trc(port
->fcs
, req_status
);
774 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
778 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
779 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
781 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
782 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
786 bfa_trc(port
->fcs
, cthdr
->reason_code
);
787 bfa_trc(port
->fcs
, cthdr
->exp_code
);
788 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
792 * RPRT : Register Port
795 bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
797 struct bfa_fcs_port_fdmi_s
*fdmi
= fdmi_cbarg
;
798 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
801 struct bfa_fcxp_s
*fcxp
;
804 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
806 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
808 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
809 bfa_fcs_port_fdmi_send_rprt
, fdmi
);
814 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
815 bfa_os_memset(pyld
, 0, FC_MAX_PDUSZ
);
817 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_port_get_fcid(port
),
820 attr_len
= bfa_fcs_port_fdmi_build_rprt_pyld(fdmi
,
821 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
823 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
824 FC_CLASS_3
, len
+ attr_len
, &fchs
,
825 bfa_fcs_port_fdmi_rprt_response
, (void *)fdmi
,
826 FC_MAX_PDUSZ
, FC_RA_TOV
);
828 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPRT_SENT
);
832 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
835 bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s
*fdmi
,
838 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr
;
839 struct fdmi_port_attr_s
*port_attrib
= (struct fdmi_port_attr_s
*) pyld
;
840 struct fdmi_attr_s
*attr
;
846 * get port attributes
848 bfa_fcs_fdmi_get_portattr(fdmi
, &fcs_port_attr
);
850 len
= sizeof(port_attrib
->attr_count
);
853 * fill out the invididual entries
855 curr_ptr
= (u8
*) &port_attrib
->port_attr
;
860 attr
= (struct fdmi_attr_s
*) curr_ptr
;
861 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES
);
862 attr
->len
= sizeof(fcs_port_attr
.supp_fc4_types
);
863 memcpy(attr
->value
, fcs_port_attr
.supp_fc4_types
, attr
->len
);
864 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
868 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
874 attr
= (struct fdmi_attr_s
*) curr_ptr
;
875 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED
);
876 attr
->len
= sizeof(fcs_port_attr
.supp_speed
);
877 memcpy(attr
->value
, &fcs_port_attr
.supp_speed
, attr
->len
);
878 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
882 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
888 attr
= (struct fdmi_attr_s
*) curr_ptr
;
889 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED
);
890 attr
->len
= sizeof(fcs_port_attr
.curr_speed
);
891 memcpy(attr
->value
, &fcs_port_attr
.curr_speed
, attr
->len
);
892 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
896 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
902 attr
= (struct fdmi_attr_s
*) curr_ptr
;
903 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE
);
904 attr
->len
= sizeof(fcs_port_attr
.max_frm_size
);
905 memcpy(attr
->value
, &fcs_port_attr
.max_frm_size
, attr
->len
);
906 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
910 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
916 if (fcs_port_attr
.os_device_name
[0] != '\0') {
917 attr
= (struct fdmi_attr_s
*) curr_ptr
;
918 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME
);
919 attr
->len
= (u16
) strlen(fcs_port_attr
.os_device_name
);
920 memcpy(attr
->value
, fcs_port_attr
.os_device_name
, attr
->len
);
921 /* variable fields need to be 4 byte aligned */
922 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
923 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
927 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
934 if (fcs_port_attr
.host_name
[0] != '\0') {
935 attr
= (struct fdmi_attr_s
*) curr_ptr
;
936 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME
);
937 attr
->len
= (u16
) strlen(fcs_port_attr
.host_name
);
938 memcpy(attr
->value
, fcs_port_attr
.host_name
, attr
->len
);
939 /* variable fields need to be 4 byte aligned */
940 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
941 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
945 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
951 * Update size of payload
953 port_attrib
->attr_count
= bfa_os_htonl(count
);
954 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
959 bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s
*fdmi
,
962 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
963 struct fdmi_rprt_s
*rprt
= (struct fdmi_rprt_s
*) pyld
;
966 rprt
->hba_id
= bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port
->fcs
));
967 rprt
->port_name
= bfa_fcs_port_get_pwwn(port
);
969 len
= bfa_fcs_port_fdmi_build_portattr_block(fdmi
,
970 (u8
*) &rprt
->port_attr_blk
);
972 len
+= sizeof(rprt
->hba_id
) + sizeof(rprt
->port_name
);
978 bfa_fcs_port_fdmi_rprt_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
979 void *cbarg
, bfa_status_t req_status
,
980 u32 rsp_len
, u32 resid_len
,
981 struct fchs_s
*rsp_fchs
)
983 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)cbarg
;
984 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
985 struct ct_hdr_s
*cthdr
= NULL
;
987 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
992 if (req_status
!= BFA_STATUS_OK
) {
993 bfa_trc(port
->fcs
, req_status
);
994 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
998 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
999 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
1001 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1002 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
1006 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1007 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1008 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1012 * RPA : Register Port Attributes.
1015 bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1017 struct bfa_fcs_port_fdmi_s
*fdmi
= fdmi_cbarg
;
1018 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1021 struct bfa_fcxp_s
*fcxp
;
1024 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1026 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1028 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
1029 bfa_fcs_port_fdmi_send_rpa
, fdmi
);
1034 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
1035 bfa_os_memset(pyld
, 0, FC_MAX_PDUSZ
);
1037 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_port_get_fcid(port
),
1040 attr_len
= bfa_fcs_port_fdmi_build_rpa_pyld(fdmi
,
1041 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
1043 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1044 FC_CLASS_3
, len
+ attr_len
, &fchs
,
1045 bfa_fcs_port_fdmi_rpa_response
, (void *)fdmi
,
1046 FC_MAX_PDUSZ
, FC_RA_TOV
);
1048 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPA_SENT
);
1052 bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s
*fdmi
,
1055 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1056 struct fdmi_rpa_s
*rpa
= (struct fdmi_rpa_s
*) pyld
;
1059 rpa
->port_name
= bfa_fcs_port_get_pwwn(port
);
1061 len
= bfa_fcs_port_fdmi_build_portattr_block(fdmi
,
1062 (u8
*) &rpa
->port_attr_blk
);
1064 len
+= sizeof(rpa
->port_name
);
1070 bfa_fcs_port_fdmi_rpa_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
1071 void *cbarg
, bfa_status_t req_status
,
1072 u32 rsp_len
, u32 resid_len
,
1073 struct fchs_s
*rsp_fchs
)
1075 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)cbarg
;
1076 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1077 struct ct_hdr_s
*cthdr
= NULL
;
1079 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1084 if (req_status
!= BFA_STATUS_OK
) {
1085 bfa_trc(port
->fcs
, req_status
);
1086 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1090 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1091 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
1093 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1094 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
1098 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1099 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1100 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1104 bfa_fcs_port_fdmi_timeout(void *arg
)
1106 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)arg
;
1108 bfa_sm_send_event(fdmi
, FDMISM_EVENT_TIMEOUT
);
1112 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
1113 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
)
1115 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1116 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
1118 bfa_os_memset(hba_attr
, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s
));
1120 bfa_ioc_get_adapter_manufacturer(&port
->fcs
->bfa
->ioc
,
1121 hba_attr
->manufacturer
);
1122 bfa_ioc_get_adapter_serial_num(&port
->fcs
->bfa
->ioc
,
1123 hba_attr
->serial_num
);
1124 bfa_ioc_get_adapter_model(&port
->fcs
->bfa
->ioc
, hba_attr
->model
);
1125 bfa_ioc_get_adapter_model(&port
->fcs
->bfa
->ioc
, hba_attr
->model_desc
);
1126 bfa_ioc_get_pci_chip_rev(&port
->fcs
->bfa
->ioc
, hba_attr
->hw_version
);
1127 bfa_ioc_get_adapter_optrom_ver(&port
->fcs
->bfa
->ioc
,
1128 hba_attr
->option_rom_ver
);
1129 bfa_ioc_get_adapter_fw_ver(&port
->fcs
->bfa
->ioc
, hba_attr
->fw_version
);
1131 strncpy(hba_attr
->driver_version
, (char *)driver_info
->version
,
1132 sizeof(hba_attr
->driver_version
));
1134 strncpy(hba_attr
->os_name
, driver_info
->host_os_name
,
1135 sizeof(hba_attr
->os_name
));
1138 * If there is a patch level, append it to the os name along with a
1141 if (driver_info
->host_os_patch
[0] != '\0') {
1142 strncat(hba_attr
->os_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
1143 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
1144 strncat(hba_attr
->os_name
, driver_info
->host_os_patch
,
1145 sizeof(driver_info
->host_os_patch
));
1148 hba_attr
->max_ct_pyld
= bfa_os_htonl(FC_MAX_PDUSZ
);
1153 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
1154 struct bfa_fcs_fdmi_port_attr_s
*port_attr
)
1156 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1157 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
1158 struct bfa_pport_attr_s pport_attr
;
1160 bfa_os_memset(port_attr
, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s
));
1163 * get pport attributes from hal
1165 bfa_fcport_get_attr(port
->fcs
->bfa
, &pport_attr
);
1168 * get FC4 type Bitmask
1170 fc_get_fc4type_bitmask(FC_TYPE_FCP
, port_attr
->supp_fc4_types
);
1175 port_attr
->supp_speed
= bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS
);
1180 port_attr
->curr_speed
= bfa_os_htonl(pport_attr
.speed
);
1185 port_attr
->max_frm_size
= bfa_os_htonl(FC_MAX_PDUSZ
);
1190 strncpy(port_attr
->os_device_name
, (char *)driver_info
->os_device_name
,
1191 sizeof(port_attr
->os_device_name
));
1196 strncpy(port_attr
->host_name
, (char *)driver_info
->host_machine_name
,
1197 sizeof(port_attr
->host_name
));
1203 bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s
*ms
)
1205 struct bfa_fcs_port_fdmi_s
*fdmi
= &ms
->fdmi
;
1208 if (ms
->port
->fcs
->fdmi_enabled
)
1209 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
1211 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_disabled
);
1215 bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s
*ms
)
1217 struct bfa_fcs_port_fdmi_s
*fdmi
= &ms
->fdmi
;
1220 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_OFFLINE
);
1224 bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s
*ms
)
1226 struct bfa_fcs_port_fdmi_s
*fdmi
= &ms
->fdmi
;
1229 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_ONLINE
);