Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[cascardo/linux.git] / drivers / scsi / bfa / fdmi.c
1 /*
2  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3  * All rights reserved
4  * www.brocade.com
5  *
6  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7  *
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
11  *
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.
16  */
17
18 /**
19  *  port_api.c BFA FCS port
20  */
21
22
23 #include <bfa.h>
24 #include <bfa_svc.h>
25 #include "fcs_lport.h"
26 #include "fcs_rport.h"
27 #include "lport_priv.h"
28 #include "fcs_trcmod.h"
29 #include "fcs_fcxp.h"
30 #include <fcs/bfa_fcs_fdmi.h>
31
32 BFA_TRC_FILE(FCS, FDMI);
33
34 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
35
36 /*
37  * forward declarations
38  */
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,
47                                                 void *cbarg,
48                                                 bfa_status_t req_status,
49                                                 u32 rsp_len,
50                                                 u32 resid_len,
51                                                 struct fchs_s *rsp_fchs);
52 static void     bfa_fcs_port_fdmi_rprt_response(void *fcsarg,
53                                                 struct bfa_fcxp_s *fcxp,
54                                                 void *cbarg,
55                                                 bfa_status_t req_status,
56                                                 u32 rsp_len,
57                                                 u32 resid_len,
58                                                 struct fchs_s *rsp_fchs);
59 static void     bfa_fcs_port_fdmi_rpa_response(void *fcsarg,
60                                                struct bfa_fcxp_s *fcxp,
61                                                void *cbarg,
62                                                bfa_status_t req_status,
63                                                u32 rsp_len,
64                                                u32 resid_len,
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);
79 /**
80  *  fcs_fdmi_sm FCS FDMI state machine
81  */
82
83 /**
84  *  FDMI State Machine events
85  */
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,
95 };
96
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 /**
120  *              Start in offline state - awaiting MS to send start.
121  */
122 static void
123 bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
124                              enum port_fdmi_event event)
125 {
126         struct bfa_fcs_port_s *port = fdmi->ms->port;
127
128         bfa_trc(port->fcs, port->port_cfg.pwwn);
129         bfa_trc(port->fcs, event);
130
131         fdmi->retry_cnt = 0;
132
133         switch (event) {
134         case FDMISM_EVENT_PORT_ONLINE:
135                 if (port->vport) {
136                         /*
137                          * For Vports, register a new port.
138                          */
139                         bfa_sm_set_state(fdmi,
140                                          bfa_fcs_port_fdmi_sm_sending_rprt);
141                         bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
142                 } else {
143                         /*
144                          * For a base port, we should first register the HBA
145                          * atribute. The HBA attribute also contains the base
146                          *  port registration.
147                          */
148                         bfa_sm_set_state(fdmi,
149                                          bfa_fcs_port_fdmi_sm_sending_rhba);
150                         bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
151                 }
152                 break;
153
154         case FDMISM_EVENT_PORT_OFFLINE:
155                 break;
156
157         default:
158                 bfa_assert(0);
159         }
160 }
161
162 static void
163 bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
164                                   enum port_fdmi_event event)
165 {
166         struct bfa_fcs_port_s *port = fdmi->ms->port;
167
168         bfa_trc(port->fcs, port->port_cfg.pwwn);
169         bfa_trc(port->fcs, event);
170
171         switch (event) {
172         case FDMISM_EVENT_RHBA_SENT:
173                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba);
174                 break;
175
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),
179                                        &fdmi->fcxp_wqe);
180                 break;
181
182         default:
183                 bfa_assert(0);
184         }
185 }
186
187 static void
188 bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
189                           enum port_fdmi_event event)
190 {
191         struct bfa_fcs_port_s *port = fdmi->ms->port;
192
193         bfa_trc(port->fcs, port->port_cfg.pwwn);
194         bfa_trc(port->fcs, event);
195
196         switch (event) {
197         case FDMISM_EVENT_RSP_ERROR:
198                 /*
199                  * if max retries have not been reached, start timer for a
200                  * delayed retry
201                  */
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);
207                 } else {
208                         /*
209                          * set state to offline
210                          */
211                         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
212                 }
213                 break;
214
215         case FDMISM_EVENT_RSP_OK:
216                 /*
217                  * Initiate Register Port Attributes
218                  */
219                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
220                 fdmi->retry_cnt = 0;
221                 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
222                 break;
223
224         case FDMISM_EVENT_PORT_OFFLINE:
225                 bfa_fcxp_discard(fdmi->fcxp);
226                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
227                 break;
228
229         default:
230                 bfa_assert(0);
231         }
232 }
233
234 static void
235 bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
236                                 enum port_fdmi_event event)
237 {
238         struct bfa_fcs_port_s *port = fdmi->ms->port;
239
240         bfa_trc(port->fcs, port->port_cfg.pwwn);
241         bfa_trc(port->fcs, event);
242
243         switch (event) {
244         case FDMISM_EVENT_TIMEOUT:
245                 /*
246                  * Retry Timer Expired. Re-send
247                  */
248                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba);
249                 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
250                 break;
251
252         case FDMISM_EVENT_PORT_OFFLINE:
253                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
254                 bfa_timer_stop(&fdmi->timer);
255                 break;
256
257         default:
258                 bfa_assert(0);
259         }
260 }
261
262 /*
263 * RPRT : Register Port
264  */
265 static void
266 bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
267                                   enum port_fdmi_event event)
268 {
269         struct bfa_fcs_port_s *port = fdmi->ms->port;
270
271         bfa_trc(port->fcs, port->port_cfg.pwwn);
272         bfa_trc(port->fcs, event);
273
274         switch (event) {
275         case FDMISM_EVENT_RPRT_SENT:
276                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt);
277                 break;
278
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),
282                                        &fdmi->fcxp_wqe);
283                 break;
284
285         default:
286                 bfa_assert(0);
287         }
288 }
289
290 static void
291 bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
292                           enum port_fdmi_event event)
293 {
294         struct bfa_fcs_port_s *port = fdmi->ms->port;
295
296         bfa_trc(port->fcs, port->port_cfg.pwwn);
297         bfa_trc(port->fcs, event);
298
299         switch (event) {
300         case FDMISM_EVENT_RSP_ERROR:
301                 /*
302                  * if max retries have not been reached, start timer for a
303                  * delayed retry
304                  */
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);
310
311                 } else {
312                         /*
313                          * set state to offline
314                          */
315                         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
316                         fdmi->retry_cnt = 0;
317                 }
318                 break;
319
320         case FDMISM_EVENT_RSP_OK:
321                 fdmi->retry_cnt = 0;
322                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
323                 break;
324
325         case FDMISM_EVENT_PORT_OFFLINE:
326                 bfa_fcxp_discard(fdmi->fcxp);
327                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
328                 break;
329
330         default:
331                 bfa_assert(0);
332         }
333 }
334
335 static void
336 bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
337                                 enum port_fdmi_event event)
338 {
339         struct bfa_fcs_port_s *port = fdmi->ms->port;
340
341         bfa_trc(port->fcs, port->port_cfg.pwwn);
342         bfa_trc(port->fcs, event);
343
344         switch (event) {
345         case FDMISM_EVENT_TIMEOUT:
346                 /*
347                  * Retry Timer Expired. Re-send
348                  */
349                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt);
350                 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
351                 break;
352
353         case FDMISM_EVENT_PORT_OFFLINE:
354                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
355                 bfa_timer_stop(&fdmi->timer);
356                 break;
357
358         default:
359                 bfa_assert(0);
360         }
361 }
362
363 /*
364  * Register Port Attributes
365  */
366 static void
367 bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
368                                  enum port_fdmi_event event)
369 {
370         struct bfa_fcs_port_s *port = fdmi->ms->port;
371
372         bfa_trc(port->fcs, port->port_cfg.pwwn);
373         bfa_trc(port->fcs, event);
374
375         switch (event) {
376         case FDMISM_EVENT_RPA_SENT:
377                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa);
378                 break;
379
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),
383                                        &fdmi->fcxp_wqe);
384                 break;
385
386         default:
387                 bfa_assert(0);
388         }
389 }
390
391 static void
392 bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
393                          enum port_fdmi_event event)
394 {
395         struct bfa_fcs_port_s *port = fdmi->ms->port;
396
397         bfa_trc(port->fcs, port->port_cfg.pwwn);
398         bfa_trc(port->fcs, event);
399
400         switch (event) {
401         case FDMISM_EVENT_RSP_ERROR:
402                 /*
403                  * if max retries have not been reached, start timer for a
404                  * delayed retry
405                  */
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);
411                 } else {
412                         /*
413                          * set state to offline
414                          */
415                         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
416                         fdmi->retry_cnt = 0;
417                 }
418                 break;
419
420         case FDMISM_EVENT_RSP_OK:
421                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
422                 fdmi->retry_cnt = 0;
423                 break;
424
425         case FDMISM_EVENT_PORT_OFFLINE:
426                 bfa_fcxp_discard(fdmi->fcxp);
427                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
428                 break;
429
430         default:
431                 bfa_assert(0);
432         }
433 }
434
435 static void
436 bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
437                                enum port_fdmi_event event)
438 {
439         struct bfa_fcs_port_s *port = fdmi->ms->port;
440
441         bfa_trc(port->fcs, port->port_cfg.pwwn);
442         bfa_trc(port->fcs, event);
443
444         switch (event) {
445         case FDMISM_EVENT_TIMEOUT:
446                 /*
447                  * Retry Timer Expired. Re-send
448                  */
449                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
450                 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
451                 break;
452
453         case FDMISM_EVENT_PORT_OFFLINE:
454                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
455                 bfa_timer_stop(&fdmi->timer);
456                 break;
457
458         default:
459                 bfa_assert(0);
460         }
461 }
462
463 static void
464 bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
465                             enum port_fdmi_event event)
466 {
467         struct bfa_fcs_port_s *port = fdmi->ms->port;
468
469         bfa_trc(port->fcs, port->port_cfg.pwwn);
470         bfa_trc(port->fcs, event);
471
472         switch (event) {
473         case FDMISM_EVENT_PORT_OFFLINE:
474                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
475                 break;
476
477         default:
478                 bfa_assert(0);
479         }
480 }
481
482
483 /**
484 *   RHBA : Register HBA Attributes.
485  */
486 static void
487 bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
488 {
489         struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
490         struct bfa_fcs_port_s *port = fdmi->ms->port;
491         struct fchs_s          fchs;
492         int             len, attr_len;
493         struct bfa_fcxp_s *fcxp;
494         u8        *pyld;
495
496         bfa_trc(port->fcs, port->port_cfg.pwwn);
497
498         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
499         if (!fcxp) {
500                 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
501                                     bfa_fcs_port_fdmi_send_rhba, fdmi);
502                 return;
503         }
504         fdmi->fcxp = fcxp;
505
506         pyld = bfa_fcxp_get_reqbuf(fcxp);
507         bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
508
509         len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
510                                    FDMI_RHBA);
511
512         attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi,
513                         (u8 *) ((struct ct_hdr_s *) pyld + 1));
514
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);
519
520         bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
521 }
522
523 static          u16
524 bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
525                                   u8 *pyld)
526 {
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;
532         u8        *curr_ptr;
533         u16        len, count;
534
535         /*
536          * get hba attributes
537          */
538         bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
539
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);
543
544         len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
545
546         count = 0;
547         len += sizeof(rhba->hba_attr_blk.attr_count);
548
549         /*
550          * fill out the invididual entries of the HBA attrib Block
551          */
552         curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
553
554         /*
555          * Node Name
556          */
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;
562         len += attr->len;
563         count++;
564         attr->len =
565                 bfa_os_htons(attr->len + sizeof(attr->type) +
566                              sizeof(attr->len));
567
568         /*
569          * Manufacturer
570          */
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;
578         len += attr->len;
579         count++;
580         attr->len =
581                 bfa_os_htons(attr->len + sizeof(attr->type) +
582                              sizeof(attr->len));
583
584         /*
585          * Serial Number
586          */
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;
594         len += attr->len;
595         count++;
596         attr->len =
597                 bfa_os_htons(attr->len + sizeof(attr->type) +
598                              sizeof(attr->len));
599
600         /*
601          * Model
602          */
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;
610         len += attr->len;
611         count++;
612         attr->len =
613                 bfa_os_htons(attr->len + sizeof(attr->type) +
614                              sizeof(attr->len));
615
616         /*
617          * Model Desc
618          */
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;
626         len += attr->len;
627         count++;
628         attr->len =
629                 bfa_os_htons(attr->len + sizeof(attr->type) +
630                              sizeof(attr->len));
631
632         /*
633          * H/W Version
634          */
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;
643                 len += attr->len;
644                 count++;
645                 attr->len =
646                         bfa_os_htons(attr->len + sizeof(attr->type) +
647                                      sizeof(attr->len));
648         }
649
650         /*
651          * Driver Version
652          */
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;
660         len += attr->len;;
661         count++;
662         attr->len =
663                 bfa_os_htons(attr->len + sizeof(attr->type) +
664                              sizeof(attr->len));
665
666         /*
667          * Option Rom Version
668          */
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;
677                 len += attr->len;
678                 count++;
679                 attr->len =
680                         bfa_os_htons(attr->len + sizeof(attr->type) +
681                                      sizeof(attr->len));
682         }
683
684         /*
685          * f/w Version = driver version
686          */
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;
694         len += attr->len;
695         count++;
696         attr->len =
697                 bfa_os_htons(attr->len + sizeof(attr->type) +
698                              sizeof(attr->len));
699
700         /*
701          * OS Name
702          */
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;
711                 len += attr->len;
712                 count++;
713                 attr->len =
714                         bfa_os_htons(attr->len + sizeof(attr->type) +
715                                      sizeof(attr->len));
716         }
717
718         /*
719          * MAX_CT_PAYLOAD
720          */
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);
725         len += attr->len;
726         count++;
727         attr->len =
728                 bfa_os_htons(attr->len + sizeof(attr->type) +
729                              sizeof(attr->len));
730
731         /*
732          * Update size of payload
733          */
734         len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
735
736         rhba->hba_attr_blk.attr_count = bfa_os_htonl(count);
737         return len;
738 }
739
740 static void
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)
745 {
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;
749
750         bfa_trc(port->fcs, port->port_cfg.pwwn);
751
752         /*
753          * Sanity Checks
754          */
755         if (req_status != BFA_STATUS_OK) {
756                 bfa_trc(port->fcs, req_status);
757                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
758                 return;
759         }
760
761         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
762         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
763
764         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
765                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
766                 return;
767         }
768
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);
772 }
773
774 /**
775 *   RPRT : Register Port
776  */
777 static void
778 bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
779 {
780         struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
781         struct bfa_fcs_port_s *port = fdmi->ms->port;
782         struct fchs_s          fchs;
783         u16        len, attr_len;
784         struct bfa_fcxp_s *fcxp;
785         u8        *pyld;
786
787         bfa_trc(port->fcs, port->port_cfg.pwwn);
788
789         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
790         if (!fcxp) {
791                 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
792                                     bfa_fcs_port_fdmi_send_rprt, fdmi);
793                 return;
794         }
795         fdmi->fcxp = fcxp;
796
797         pyld = bfa_fcxp_get_reqbuf(fcxp);
798         bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
799
800         len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
801                                    FDMI_RPRT);
802
803         attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi,
804                         (u8 *) ((struct ct_hdr_s *) pyld + 1));
805
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);
810
811         bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
812 }
813
814 /**
815  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
816  */
817 static          u16
818 bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi,
819                                        u8 *pyld)
820 {
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;
824         u8        *curr_ptr;
825         u16        len;
826         u8         count = 0;
827
828         /*
829          * get port attributes
830          */
831         bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
832
833         len = sizeof(port_attrib->attr_count);
834
835         /*
836          * fill out the invididual entries
837          */
838         curr_ptr = (u8 *) &port_attrib->port_attr;
839
840         /*
841          * FC4 Types
842          */
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;
848         len += attr->len;
849         ++count;
850         attr->len =
851                 bfa_os_htons(attr->len + sizeof(attr->type) +
852                              sizeof(attr->len));
853
854         /*
855          * Supported Speed
856          */
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;
862         len += attr->len;
863         ++count;
864         attr->len =
865                 bfa_os_htons(attr->len + sizeof(attr->type) +
866                              sizeof(attr->len));
867
868         /*
869          * current Port Speed
870          */
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;
876         len += attr->len;
877         ++count;
878         attr->len =
879                 bfa_os_htons(attr->len + sizeof(attr->type) +
880                              sizeof(attr->len));
881
882         /*
883          * max frame size
884          */
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;
890         len += attr->len;
891         ++count;
892         attr->len =
893                 bfa_os_htons(attr->len + sizeof(attr->type) +
894                              sizeof(attr->len));
895
896         /*
897          * OS Device Name
898          */
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;
907                 len += attr->len;
908                 ++count;
909                 attr->len =
910                         bfa_os_htons(attr->len + sizeof(attr->type) +
911                                      sizeof(attr->len));
912
913         }
914         /*
915          * Host Name
916          */
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;
925                 len += attr->len;
926                 ++count;
927                 attr->len =
928                         bfa_os_htons(attr->len + sizeof(attr->type) +
929                                      sizeof(attr->len));
930
931         }
932
933         /*
934          * Update size of payload
935          */
936         port_attrib->attr_count = bfa_os_htonl(count);
937         len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
938         return len;
939 }
940
941 static          u16
942 bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
943                                   u8 *pyld)
944 {
945         struct bfa_fcs_port_s *port = fdmi->ms->port;
946         struct fdmi_rprt_s    *rprt = (struct fdmi_rprt_s *) pyld;
947         u16        len;
948
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);
951
952         len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
953                         (u8 *) &rprt->port_attr_blk);
954
955         len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
956
957         return len;
958 }
959
960 static void
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)
965 {
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;
969
970         bfa_trc(port->fcs, port->port_cfg.pwwn);
971
972         /*
973          * Sanity Checks
974          */
975         if (req_status != BFA_STATUS_OK) {
976                 bfa_trc(port->fcs, req_status);
977                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
978                 return;
979         }
980
981         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
982         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
983
984         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
985                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
986                 return;
987         }
988
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);
992 }
993
994 /**
995 *   RPA : Register Port Attributes.
996  */
997 static void
998 bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
999 {
1000         struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
1001         struct bfa_fcs_port_s *port = fdmi->ms->port;
1002         struct fchs_s          fchs;
1003         u16        len, attr_len;
1004         struct bfa_fcxp_s *fcxp;
1005         u8        *pyld;
1006
1007         bfa_trc(port->fcs, port->port_cfg.pwwn);
1008
1009         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1010         if (!fcxp) {
1011                 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1012                                     bfa_fcs_port_fdmi_send_rpa, fdmi);
1013                 return;
1014         }
1015         fdmi->fcxp = fcxp;
1016
1017         pyld = bfa_fcxp_get_reqbuf(fcxp);
1018         bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
1019
1020         len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
1021                                    FDMI_RPA);
1022
1023         attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi,
1024                         (u8 *) ((struct ct_hdr_s *) pyld + 1));
1025
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);
1030
1031         bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
1032 }
1033
1034 static          u16
1035 bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
1036                                  u8 *pyld)
1037 {
1038         struct bfa_fcs_port_s *port = fdmi->ms->port;
1039         struct fdmi_rpa_s     *rpa = (struct fdmi_rpa_s *) pyld;
1040         u16        len;
1041
1042         rpa->port_name = bfa_fcs_port_get_pwwn(port);
1043
1044         len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
1045                         (u8 *) &rpa->port_attr_blk);
1046
1047         len += sizeof(rpa->port_name);
1048
1049         return len;
1050 }
1051
1052 static void
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)
1057 {
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;
1061
1062         bfa_trc(port->fcs, port->port_cfg.pwwn);
1063
1064         /*
1065          * Sanity Checks
1066          */
1067         if (req_status != BFA_STATUS_OK) {
1068                 bfa_trc(port->fcs, req_status);
1069                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1070                 return;
1071         }
1072
1073         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1074         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1075
1076         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1077                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1078                 return;
1079         }
1080
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);
1084 }
1085
1086 static void
1087 bfa_fcs_port_fdmi_timeout(void *arg)
1088 {
1089         struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg;
1090
1091         bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
1092 }
1093
1094 void
1095 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
1096                          struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
1097 {
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;
1101
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));
1104
1105         bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
1106
1107         strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
1108                 sizeof(adapter_attr.manufacturer));
1109
1110         strncpy(hba_attr->serial_num, adapter_attr.serial_num,
1111                 sizeof(adapter_attr.serial_num));
1112
1113         strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
1114
1115         strncpy(hba_attr->model_desc, adapter_attr.model_descr,
1116                 sizeof(hba_attr->model_desc));
1117
1118         strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
1119                 sizeof(hba_attr->hw_version));
1120
1121         strncpy(hba_attr->driver_version, (char *)driver_info->version,
1122                 sizeof(hba_attr->driver_version));
1123
1124         strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
1125                 sizeof(hba_attr->option_rom_ver));
1126
1127         strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
1128                 sizeof(hba_attr->fw_version));
1129
1130         strncpy(hba_attr->os_name, driver_info->host_os_name,
1131                 sizeof(hba_attr->os_name));
1132
1133         /*
1134          * If there is a patch level, append it to the os name along with a
1135          * separator
1136          */
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));
1142         }
1143
1144         hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ);
1145
1146 }
1147
1148 void
1149 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
1150                           struct bfa_fcs_fdmi_port_attr_s *port_attr)
1151 {
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;
1155
1156         bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
1157
1158         /*
1159          * get pport attributes from hal
1160          */
1161         bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
1162
1163         /*
1164          * get FC4 type Bitmask
1165          */
1166         fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
1167
1168         /*
1169          * Supported Speeds
1170          */
1171         port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS);
1172
1173         /*
1174          * Current Speed
1175          */
1176         port_attr->curr_speed = bfa_os_htonl(pport_attr.speed);
1177
1178         /*
1179          * Max PDU Size.
1180          */
1181         port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ);
1182
1183         /*
1184          * OS device Name
1185          */
1186         strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
1187                 sizeof(port_attr->os_device_name));
1188
1189         /*
1190          * Host name
1191          */
1192         strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
1193                 sizeof(port_attr->host_name));
1194
1195 }
1196
1197
1198 void
1199 bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
1200 {
1201         struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1202
1203         fdmi->ms = ms;
1204         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
1205 }
1206
1207 void
1208 bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms)
1209 {
1210         struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1211
1212         fdmi->ms = ms;
1213         bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
1214 }
1215
1216 void
1217 bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms)
1218 {
1219         struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1220
1221         fdmi->ms = ms;
1222         bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
1223 }