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 void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
76 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
);
77 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
);
120 * Start in offline state - awaiting MS to send start.
123 bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s
*fdmi
,
124 enum port_fdmi_event event
)
126 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
128 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
129 bfa_trc(port
->fcs
, event
);
134 case FDMISM_EVENT_PORT_ONLINE
:
137 * For Vports, register a new port.
139 bfa_sm_set_state(fdmi
,
140 bfa_fcs_port_fdmi_sm_sending_rprt
);
141 bfa_fcs_port_fdmi_send_rprt(fdmi
, NULL
);
144 * For a base port, we should first register the HBA
145 * atribute. The HBA attribute also contains the base
148 bfa_sm_set_state(fdmi
,
149 bfa_fcs_port_fdmi_sm_sending_rhba
);
150 bfa_fcs_port_fdmi_send_rhba(fdmi
, NULL
);
154 case FDMISM_EVENT_PORT_OFFLINE
:
163 bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s
*fdmi
,
164 enum port_fdmi_event event
)
166 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
168 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
169 bfa_trc(port
->fcs
, event
);
172 case FDMISM_EVENT_RHBA_SENT
:
173 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rhba
);
176 case FDMISM_EVENT_PORT_OFFLINE
:
177 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
178 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
188 bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s
*fdmi
,
189 enum port_fdmi_event event
)
191 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
193 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
194 bfa_trc(port
->fcs
, event
);
197 case FDMISM_EVENT_RSP_ERROR
:
199 * if max retries have not been reached, start timer for a
202 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
203 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rhba_retry
);
204 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
205 &fdmi
->timer
, bfa_fcs_port_fdmi_timeout
,
206 fdmi
, BFA_FCS_RETRY_TIMEOUT
);
209 * set state to offline
211 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
215 case FDMISM_EVENT_RSP_OK
:
217 * Initiate Register Port Attributes
219 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rpa
);
221 bfa_fcs_port_fdmi_send_rpa(fdmi
, NULL
);
224 case FDMISM_EVENT_PORT_OFFLINE
:
225 bfa_fcxp_discard(fdmi
->fcxp
);
226 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
235 bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
236 enum port_fdmi_event event
)
238 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
240 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
241 bfa_trc(port
->fcs
, event
);
244 case FDMISM_EVENT_TIMEOUT
:
246 * Retry Timer Expired. Re-send
248 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rhba
);
249 bfa_fcs_port_fdmi_send_rhba(fdmi
, NULL
);
252 case FDMISM_EVENT_PORT_OFFLINE
:
253 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
254 bfa_timer_stop(&fdmi
->timer
);
263 * RPRT : Register Port
266 bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s
*fdmi
,
267 enum port_fdmi_event event
)
269 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
271 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
272 bfa_trc(port
->fcs
, event
);
275 case FDMISM_EVENT_RPRT_SENT
:
276 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rprt
);
279 case FDMISM_EVENT_PORT_OFFLINE
:
280 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
281 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
291 bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s
*fdmi
,
292 enum port_fdmi_event event
)
294 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
296 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
297 bfa_trc(port
->fcs
, event
);
300 case FDMISM_EVENT_RSP_ERROR
:
302 * if max retries have not been reached, start timer for a
305 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
306 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rprt_retry
);
307 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
308 &fdmi
->timer
, bfa_fcs_port_fdmi_timeout
,
309 fdmi
, BFA_FCS_RETRY_TIMEOUT
);
313 * set state to offline
315 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
320 case FDMISM_EVENT_RSP_OK
:
322 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_online
);
325 case FDMISM_EVENT_PORT_OFFLINE
:
326 bfa_fcxp_discard(fdmi
->fcxp
);
327 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
336 bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
337 enum port_fdmi_event event
)
339 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
341 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
342 bfa_trc(port
->fcs
, event
);
345 case FDMISM_EVENT_TIMEOUT
:
347 * Retry Timer Expired. Re-send
349 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rprt
);
350 bfa_fcs_port_fdmi_send_rprt(fdmi
, NULL
);
353 case FDMISM_EVENT_PORT_OFFLINE
:
354 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
355 bfa_timer_stop(&fdmi
->timer
);
364 * Register Port Attributes
367 bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s
*fdmi
,
368 enum port_fdmi_event event
)
370 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
372 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
373 bfa_trc(port
->fcs
, event
);
376 case FDMISM_EVENT_RPA_SENT
:
377 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rpa
);
380 case FDMISM_EVENT_PORT_OFFLINE
:
381 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
382 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port
),
392 bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s
*fdmi
,
393 enum port_fdmi_event event
)
395 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
397 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
398 bfa_trc(port
->fcs
, event
);
401 case FDMISM_EVENT_RSP_ERROR
:
403 * if max retries have not been reached, start timer for a
406 if (fdmi
->retry_cnt
++ < BFA_FCS_FDMI_CMD_MAX_RETRIES
) {
407 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_rpa_retry
);
408 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port
),
409 &fdmi
->timer
, bfa_fcs_port_fdmi_timeout
,
410 fdmi
, BFA_FCS_RETRY_TIMEOUT
);
413 * set state to offline
415 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
420 case FDMISM_EVENT_RSP_OK
:
421 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_online
);
425 case FDMISM_EVENT_PORT_OFFLINE
:
426 bfa_fcxp_discard(fdmi
->fcxp
);
427 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
436 bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s
*fdmi
,
437 enum port_fdmi_event event
)
439 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
441 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
442 bfa_trc(port
->fcs
, event
);
445 case FDMISM_EVENT_TIMEOUT
:
447 * Retry Timer Expired. Re-send
449 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_sending_rpa
);
450 bfa_fcs_port_fdmi_send_rpa(fdmi
, NULL
);
453 case FDMISM_EVENT_PORT_OFFLINE
:
454 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
455 bfa_timer_stop(&fdmi
->timer
);
464 bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s
*fdmi
,
465 enum port_fdmi_event event
)
467 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
469 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
470 bfa_trc(port
->fcs
, event
);
473 case FDMISM_EVENT_PORT_OFFLINE
:
474 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
484 * RHBA : Register HBA Attributes.
487 bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
489 struct bfa_fcs_port_fdmi_s
*fdmi
= fdmi_cbarg
;
490 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
493 struct bfa_fcxp_s
*fcxp
;
496 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
498 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
500 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
501 bfa_fcs_port_fdmi_send_rhba
, fdmi
);
506 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
507 bfa_os_memset(pyld
, 0, FC_MAX_PDUSZ
);
509 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_port_get_fcid(port
),
512 attr_len
= bfa_fcs_port_fdmi_build_rhba_pyld(fdmi
,
513 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
515 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
516 FC_CLASS_3
, (len
+ attr_len
), &fchs
,
517 bfa_fcs_port_fdmi_rhba_response
, (void *)fdmi
,
518 FC_MAX_PDUSZ
, FC_RA_TOV
);
520 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RHBA_SENT
);
524 bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s
*fdmi
,
527 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
528 struct bfa_fcs_fdmi_hba_attr_s hba_attr
; /* @todo */
529 struct bfa_fcs_fdmi_hba_attr_s
*fcs_hba_attr
= &hba_attr
; /* @todo */
530 struct fdmi_rhba_s
*rhba
= (struct fdmi_rhba_s
*) pyld
;
531 struct fdmi_attr_s
*attr
;
538 bfa_fcs_fdmi_get_hbaattr(fdmi
, fcs_hba_attr
);
540 rhba
->hba_id
= bfa_fcs_port_get_pwwn(port
);
541 rhba
->port_list
.num_ports
= bfa_os_htonl(1);
542 rhba
->port_list
.port_entry
= bfa_fcs_port_get_pwwn(port
);
544 len
= sizeof(rhba
->hba_id
) + sizeof(rhba
->port_list
);
547 len
+= sizeof(rhba
->hba_attr_blk
.attr_count
);
550 * fill out the invididual entries of the HBA attrib Block
552 curr_ptr
= (u8
*) &rhba
->hba_attr_blk
.hba_attr
;
557 attr
= (struct fdmi_attr_s
*) curr_ptr
;
558 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME
);
559 attr
->len
= sizeof(wwn_t
);
560 memcpy(attr
->value
, &bfa_fcs_port_get_nwwn(port
), attr
->len
);
561 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
565 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
571 attr
= (struct fdmi_attr_s
*) curr_ptr
;
572 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER
);
573 attr
->len
= (u16
) strlen(fcs_hba_attr
->manufacturer
);
574 memcpy(attr
->value
, fcs_hba_attr
->manufacturer
, attr
->len
);
575 /* variable fields need to be 4 byte aligned */
576 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
577 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
581 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
587 attr
= (struct fdmi_attr_s
*) curr_ptr
;
588 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM
);
589 attr
->len
= (u16
) strlen(fcs_hba_attr
->serial_num
);
590 memcpy(attr
->value
, fcs_hba_attr
->serial_num
, attr
->len
);
591 /* variable fields need to be 4 byte aligned */
592 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
593 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
597 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
603 attr
= (struct fdmi_attr_s
*) curr_ptr
;
604 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MODEL
);
605 attr
->len
= (u16
) strlen(fcs_hba_attr
->model
);
606 memcpy(attr
->value
, fcs_hba_attr
->model
, attr
->len
);
607 /* variable fields need to be 4 byte aligned */
608 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
609 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
613 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
619 attr
= (struct fdmi_attr_s
*) curr_ptr
;
620 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC
);
621 attr
->len
= (u16
) strlen(fcs_hba_attr
->model_desc
);
622 memcpy(attr
->value
, fcs_hba_attr
->model_desc
, attr
->len
);
623 /* variable fields need to be 4 byte aligned */
624 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
625 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
629 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
635 if (fcs_hba_attr
->hw_version
[0] != '\0') {
636 attr
= (struct fdmi_attr_s
*) curr_ptr
;
637 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION
);
638 attr
->len
= (u16
) strlen(fcs_hba_attr
->hw_version
);
639 memcpy(attr
->value
, fcs_hba_attr
->hw_version
, 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
) +
653 attr
= (struct fdmi_attr_s
*) curr_ptr
;
654 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION
);
655 attr
->len
= (u16
) strlen(fcs_hba_attr
->driver_version
);
656 memcpy(attr
->value
, fcs_hba_attr
->driver_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
) +
669 if (fcs_hba_attr
->option_rom_ver
[0] != '\0') {
670 attr
= (struct fdmi_attr_s
*) curr_ptr
;
671 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION
);
672 attr
->len
= (u16
) strlen(fcs_hba_attr
->option_rom_ver
);
673 memcpy(attr
->value
, fcs_hba_attr
->option_rom_ver
, 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
) +
685 * f/w Version = driver version
687 attr
= (struct fdmi_attr_s
*) curr_ptr
;
688 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION
);
689 attr
->len
= (u16
) strlen(fcs_hba_attr
->driver_version
);
690 memcpy(attr
->value
, fcs_hba_attr
->driver_version
, 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
) +
703 if (fcs_hba_attr
->os_name
[0] != '\0') {
704 attr
= (struct fdmi_attr_s
*) curr_ptr
;
705 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME
);
706 attr
->len
= (u16
) strlen(fcs_hba_attr
->os_name
);
707 memcpy(attr
->value
, fcs_hba_attr
->os_name
, 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
) +
721 attr
= (struct fdmi_attr_s
*) curr_ptr
;
722 attr
->type
= bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT
);
723 attr
->len
= sizeof(fcs_hba_attr
->max_ct_pyld
);
724 memcpy(attr
->value
, &fcs_hba_attr
->max_ct_pyld
, attr
->len
);
728 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
732 * Update size of payload
734 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
736 rhba
->hba_attr_blk
.attr_count
= bfa_os_htonl(count
);
741 bfa_fcs_port_fdmi_rhba_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
742 void *cbarg
, bfa_status_t req_status
,
743 u32 rsp_len
, u32 resid_len
,
744 struct fchs_s
*rsp_fchs
)
746 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)cbarg
;
747 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
748 struct ct_hdr_s
*cthdr
= NULL
;
750 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
755 if (req_status
!= BFA_STATUS_OK
) {
756 bfa_trc(port
->fcs
, req_status
);
757 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
761 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
762 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
764 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
765 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
769 bfa_trc(port
->fcs
, cthdr
->reason_code
);
770 bfa_trc(port
->fcs
, cthdr
->exp_code
);
771 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
775 * RPRT : Register Port
778 bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
780 struct bfa_fcs_port_fdmi_s
*fdmi
= fdmi_cbarg
;
781 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
784 struct bfa_fcxp_s
*fcxp
;
787 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
789 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
791 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
792 bfa_fcs_port_fdmi_send_rprt
, fdmi
);
797 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
798 bfa_os_memset(pyld
, 0, FC_MAX_PDUSZ
);
800 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_port_get_fcid(port
),
803 attr_len
= bfa_fcs_port_fdmi_build_rprt_pyld(fdmi
,
804 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
806 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
807 FC_CLASS_3
, len
+ attr_len
, &fchs
,
808 bfa_fcs_port_fdmi_rprt_response
, (void *)fdmi
,
809 FC_MAX_PDUSZ
, FC_RA_TOV
);
811 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPRT_SENT
);
815 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
818 bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s
*fdmi
,
821 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr
;
822 struct fdmi_port_attr_s
*port_attrib
= (struct fdmi_port_attr_s
*) pyld
;
823 struct fdmi_attr_s
*attr
;
829 * get port attributes
831 bfa_fcs_fdmi_get_portattr(fdmi
, &fcs_port_attr
);
833 len
= sizeof(port_attrib
->attr_count
);
836 * fill out the invididual entries
838 curr_ptr
= (u8
*) &port_attrib
->port_attr
;
843 attr
= (struct fdmi_attr_s
*) curr_ptr
;
844 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES
);
845 attr
->len
= sizeof(fcs_port_attr
.supp_fc4_types
);
846 memcpy(attr
->value
, fcs_port_attr
.supp_fc4_types
, attr
->len
);
847 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
851 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
857 attr
= (struct fdmi_attr_s
*) curr_ptr
;
858 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED
);
859 attr
->len
= sizeof(fcs_port_attr
.supp_speed
);
860 memcpy(attr
->value
, &fcs_port_attr
.supp_speed
, attr
->len
);
861 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
865 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
871 attr
= (struct fdmi_attr_s
*) curr_ptr
;
872 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED
);
873 attr
->len
= sizeof(fcs_port_attr
.curr_speed
);
874 memcpy(attr
->value
, &fcs_port_attr
.curr_speed
, attr
->len
);
875 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
879 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
885 attr
= (struct fdmi_attr_s
*) curr_ptr
;
886 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE
);
887 attr
->len
= sizeof(fcs_port_attr
.max_frm_size
);
888 memcpy(attr
->value
, &fcs_port_attr
.max_frm_size
, attr
->len
);
889 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
893 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
899 if (fcs_port_attr
.os_device_name
[0] != '\0') {
900 attr
= (struct fdmi_attr_s
*) curr_ptr
;
901 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME
);
902 attr
->len
= (u16
) strlen(fcs_port_attr
.os_device_name
);
903 memcpy(attr
->value
, fcs_port_attr
.os_device_name
, attr
->len
);
904 /* variable fields need to be 4 byte aligned */
905 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
906 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
910 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
917 if (fcs_port_attr
.host_name
[0] != '\0') {
918 attr
= (struct fdmi_attr_s
*) curr_ptr
;
919 attr
->type
= bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME
);
920 attr
->len
= (u16
) strlen(fcs_port_attr
.host_name
);
921 memcpy(attr
->value
, fcs_port_attr
.host_name
, attr
->len
);
922 /* variable fields need to be 4 byte aligned */
923 attr
->len
= fc_roundup(attr
->len
, sizeof(u32
));
924 curr_ptr
+= sizeof(attr
->type
) + sizeof(attr
->len
) + attr
->len
;
928 bfa_os_htons(attr
->len
+ sizeof(attr
->type
) +
934 * Update size of payload
936 port_attrib
->attr_count
= bfa_os_htonl(count
);
937 len
+= ((sizeof(attr
->type
) + sizeof(attr
->len
)) * count
);
942 bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s
*fdmi
,
945 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
946 struct fdmi_rprt_s
*rprt
= (struct fdmi_rprt_s
*) pyld
;
949 rprt
->hba_id
= bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port
->fcs
));
950 rprt
->port_name
= bfa_fcs_port_get_pwwn(port
);
952 len
= bfa_fcs_port_fdmi_build_portattr_block(fdmi
,
953 (u8
*) &rprt
->port_attr_blk
);
955 len
+= sizeof(rprt
->hba_id
) + sizeof(rprt
->port_name
);
961 bfa_fcs_port_fdmi_rprt_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
962 void *cbarg
, bfa_status_t req_status
,
963 u32 rsp_len
, u32 resid_len
,
964 struct fchs_s
*rsp_fchs
)
966 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)cbarg
;
967 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
968 struct ct_hdr_s
*cthdr
= NULL
;
970 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
975 if (req_status
!= BFA_STATUS_OK
) {
976 bfa_trc(port
->fcs
, req_status
);
977 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
981 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
982 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
984 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
985 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
989 bfa_trc(port
->fcs
, cthdr
->reason_code
);
990 bfa_trc(port
->fcs
, cthdr
->exp_code
);
991 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
995 * RPA : Register Port Attributes.
998 bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1000 struct bfa_fcs_port_fdmi_s
*fdmi
= fdmi_cbarg
;
1001 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1004 struct bfa_fcxp_s
*fcxp
;
1007 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1009 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1011 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &fdmi
->fcxp_wqe
,
1012 bfa_fcs_port_fdmi_send_rpa
, fdmi
);
1017 pyld
= bfa_fcxp_get_reqbuf(fcxp
);
1018 bfa_os_memset(pyld
, 0, FC_MAX_PDUSZ
);
1020 len
= fc_fdmi_reqhdr_build(&fchs
, pyld
, bfa_fcs_port_get_fcid(port
),
1023 attr_len
= bfa_fcs_port_fdmi_build_rpa_pyld(fdmi
,
1024 (u8
*) ((struct ct_hdr_s
*) pyld
+ 1));
1026 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1027 FC_CLASS_3
, len
+ attr_len
, &fchs
,
1028 bfa_fcs_port_fdmi_rpa_response
, (void *)fdmi
,
1029 FC_MAX_PDUSZ
, FC_RA_TOV
);
1031 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RPA_SENT
);
1035 bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s
*fdmi
,
1038 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1039 struct fdmi_rpa_s
*rpa
= (struct fdmi_rpa_s
*) pyld
;
1042 rpa
->port_name
= bfa_fcs_port_get_pwwn(port
);
1044 len
= bfa_fcs_port_fdmi_build_portattr_block(fdmi
,
1045 (u8
*) &rpa
->port_attr_blk
);
1047 len
+= sizeof(rpa
->port_name
);
1053 bfa_fcs_port_fdmi_rpa_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
1054 void *cbarg
, bfa_status_t req_status
,
1055 u32 rsp_len
, u32 resid_len
,
1056 struct fchs_s
*rsp_fchs
)
1058 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)cbarg
;
1059 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1060 struct ct_hdr_s
*cthdr
= NULL
;
1062 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1067 if (req_status
!= BFA_STATUS_OK
) {
1068 bfa_trc(port
->fcs
, req_status
);
1069 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1073 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1074 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
1076 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1077 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_OK
);
1081 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1082 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1083 bfa_sm_send_event(fdmi
, FDMISM_EVENT_RSP_ERROR
);
1087 bfa_fcs_port_fdmi_timeout(void *arg
)
1089 struct bfa_fcs_port_fdmi_s
*fdmi
= (struct bfa_fcs_port_fdmi_s
*)arg
;
1091 bfa_sm_send_event(fdmi
, FDMISM_EVENT_TIMEOUT
);
1095 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
1096 struct bfa_fcs_fdmi_hba_attr_s
*hba_attr
)
1098 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1099 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
1100 struct bfa_adapter_attr_s adapter_attr
;
1102 bfa_os_memset(hba_attr
, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s
));
1103 bfa_os_memset(&adapter_attr
, 0, sizeof(struct bfa_adapter_attr_s
));
1105 bfa_ioc_get_adapter_attr(&port
->fcs
->bfa
->ioc
, &adapter_attr
);
1107 strncpy(hba_attr
->manufacturer
, adapter_attr
.manufacturer
,
1108 sizeof(adapter_attr
.manufacturer
));
1110 strncpy(hba_attr
->serial_num
, adapter_attr
.serial_num
,
1111 sizeof(adapter_attr
.serial_num
));
1113 strncpy(hba_attr
->model
, adapter_attr
.model
, sizeof(hba_attr
->model
));
1115 strncpy(hba_attr
->model_desc
, adapter_attr
.model_descr
,
1116 sizeof(hba_attr
->model_desc
));
1118 strncpy(hba_attr
->hw_version
, adapter_attr
.hw_ver
,
1119 sizeof(hba_attr
->hw_version
));
1121 strncpy(hba_attr
->driver_version
, (char *)driver_info
->version
,
1122 sizeof(hba_attr
->driver_version
));
1124 strncpy(hba_attr
->option_rom_ver
, adapter_attr
.optrom_ver
,
1125 sizeof(hba_attr
->option_rom_ver
));
1127 strncpy(hba_attr
->fw_version
, adapter_attr
.fw_ver
,
1128 sizeof(hba_attr
->fw_version
));
1130 strncpy(hba_attr
->os_name
, driver_info
->host_os_name
,
1131 sizeof(hba_attr
->os_name
));
1134 * If there is a patch level, append it to the os name along with a
1137 if (driver_info
->host_os_patch
[0] != '\0') {
1138 strncat(hba_attr
->os_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
1139 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
1140 strncat(hba_attr
->os_name
, driver_info
->host_os_patch
,
1141 sizeof(driver_info
->host_os_patch
));
1144 hba_attr
->max_ct_pyld
= bfa_os_htonl(FC_MAX_PDUSZ
);
1149 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s
*fdmi
,
1150 struct bfa_fcs_fdmi_port_attr_s
*port_attr
)
1152 struct bfa_fcs_port_s
*port
= fdmi
->ms
->port
;
1153 struct bfa_fcs_driver_info_s
*driver_info
= &port
->fcs
->driver_info
;
1154 struct bfa_pport_attr_s pport_attr
;
1156 bfa_os_memset(port_attr
, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s
));
1159 * get pport attributes from hal
1161 bfa_pport_get_attr(port
->fcs
->bfa
, &pport_attr
);
1164 * get FC4 type Bitmask
1166 fc_get_fc4type_bitmask(FC_TYPE_FCP
, port_attr
->supp_fc4_types
);
1171 port_attr
->supp_speed
= bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS
);
1176 port_attr
->curr_speed
= bfa_os_htonl(pport_attr
.speed
);
1181 port_attr
->max_frm_size
= bfa_os_htonl(FC_MAX_PDUSZ
);
1186 strncpy(port_attr
->os_device_name
, (char *)driver_info
->os_device_name
,
1187 sizeof(port_attr
->os_device_name
));
1192 strncpy(port_attr
->host_name
, (char *)driver_info
->host_machine_name
,
1193 sizeof(port_attr
->host_name
));
1199 bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s
*ms
)
1201 struct bfa_fcs_port_fdmi_s
*fdmi
= &ms
->fdmi
;
1204 bfa_sm_set_state(fdmi
, bfa_fcs_port_fdmi_sm_offline
);
1208 bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s
*ms
)
1210 struct bfa_fcs_port_fdmi_s
*fdmi
= &ms
->fdmi
;
1213 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_OFFLINE
);
1217 bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s
*ms
)
1219 struct bfa_fcs_port_fdmi_s
*fdmi
= &ms
->fdmi
;
1222 bfa_sm_send_event(fdmi
, FDMISM_EVENT_PORT_ONLINE
);