Staging: Merge staging-next into Linus's tree
[sfrench/cifs-2.6.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 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);
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 static void     bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
120                         enum port_fdmi_event event);
121
122 /**
123  *              Start in offline state - awaiting MS to send start.
124  */
125 static void
126 bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
127                              enum port_fdmi_event event)
128 {
129         struct bfa_fcs_port_s *port = fdmi->ms->port;
130
131         bfa_trc(port->fcs, port->port_cfg.pwwn);
132         bfa_trc(port->fcs, event);
133
134         fdmi->retry_cnt = 0;
135
136         switch (event) {
137         case FDMISM_EVENT_PORT_ONLINE:
138                 if (port->vport) {
139                         /*
140                          * For Vports, register a new port.
141                          */
142                         bfa_sm_set_state(fdmi,
143                                          bfa_fcs_port_fdmi_sm_sending_rprt);
144                         bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
145                 } else {
146                         /*
147                          * For a base port, we should first register the HBA
148                          * atribute. The HBA attribute also contains the base
149                          *  port registration.
150                          */
151                         bfa_sm_set_state(fdmi,
152                                          bfa_fcs_port_fdmi_sm_sending_rhba);
153                         bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
154                 }
155                 break;
156
157         case FDMISM_EVENT_PORT_OFFLINE:
158                 break;
159
160         default:
161                 bfa_sm_fault(port->fcs, event);
162         }
163 }
164
165 static void
166 bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
167                                   enum port_fdmi_event event)
168 {
169         struct bfa_fcs_port_s *port = fdmi->ms->port;
170
171         bfa_trc(port->fcs, port->port_cfg.pwwn);
172         bfa_trc(port->fcs, event);
173
174         switch (event) {
175         case FDMISM_EVENT_RHBA_SENT:
176                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba);
177                 break;
178
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),
182                                        &fdmi->fcxp_wqe);
183                 break;
184
185         default:
186                 bfa_sm_fault(port->fcs, event);
187         }
188 }
189
190 static void
191 bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
192                           enum port_fdmi_event event)
193 {
194         struct bfa_fcs_port_s *port = fdmi->ms->port;
195
196         bfa_trc(port->fcs, port->port_cfg.pwwn);
197         bfa_trc(port->fcs, event);
198
199         switch (event) {
200         case FDMISM_EVENT_RSP_ERROR:
201                 /*
202                  * if max retries have not been reached, start timer for a
203                  * delayed retry
204                  */
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);
210                 } else {
211                         /*
212                          * set state to offline
213                          */
214                         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
215                 }
216                 break;
217
218         case FDMISM_EVENT_RSP_OK:
219                 /*
220                  * Initiate Register Port Attributes
221                  */
222                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
223                 fdmi->retry_cnt = 0;
224                 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
225                 break;
226
227         case FDMISM_EVENT_PORT_OFFLINE:
228                 bfa_fcxp_discard(fdmi->fcxp);
229                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
230                 break;
231
232         default:
233                 bfa_sm_fault(port->fcs, event);
234         }
235 }
236
237 static void
238 bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
239                                 enum port_fdmi_event event)
240 {
241         struct bfa_fcs_port_s *port = fdmi->ms->port;
242
243         bfa_trc(port->fcs, port->port_cfg.pwwn);
244         bfa_trc(port->fcs, event);
245
246         switch (event) {
247         case FDMISM_EVENT_TIMEOUT:
248                 /*
249                  * Retry Timer Expired. Re-send
250                  */
251                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba);
252                 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
253                 break;
254
255         case FDMISM_EVENT_PORT_OFFLINE:
256                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
257                 bfa_timer_stop(&fdmi->timer);
258                 break;
259
260         default:
261                 bfa_sm_fault(port->fcs, event);
262         }
263 }
264
265 /*
266 * RPRT : Register Port
267  */
268 static void
269 bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
270                                   enum port_fdmi_event event)
271 {
272         struct bfa_fcs_port_s *port = fdmi->ms->port;
273
274         bfa_trc(port->fcs, port->port_cfg.pwwn);
275         bfa_trc(port->fcs, event);
276
277         switch (event) {
278         case FDMISM_EVENT_RPRT_SENT:
279                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt);
280                 break;
281
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),
285                                        &fdmi->fcxp_wqe);
286                 break;
287
288         default:
289                 bfa_sm_fault(port->fcs, event);
290         }
291 }
292
293 static void
294 bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
295                           enum port_fdmi_event event)
296 {
297         struct bfa_fcs_port_s *port = fdmi->ms->port;
298
299         bfa_trc(port->fcs, port->port_cfg.pwwn);
300         bfa_trc(port->fcs, event);
301
302         switch (event) {
303         case FDMISM_EVENT_RSP_ERROR:
304                 /*
305                  * if max retries have not been reached, start timer for a
306                  * delayed retry
307                  */
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);
313
314                 } else {
315                         /*
316                          * set state to offline
317                          */
318                         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
319                         fdmi->retry_cnt = 0;
320                 }
321                 break;
322
323         case FDMISM_EVENT_RSP_OK:
324                 fdmi->retry_cnt = 0;
325                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
326                 break;
327
328         case FDMISM_EVENT_PORT_OFFLINE:
329                 bfa_fcxp_discard(fdmi->fcxp);
330                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
331                 break;
332
333         default:
334                 bfa_sm_fault(port->fcs, event);
335         }
336 }
337
338 static void
339 bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
340                                 enum port_fdmi_event event)
341 {
342         struct bfa_fcs_port_s *port = fdmi->ms->port;
343
344         bfa_trc(port->fcs, port->port_cfg.pwwn);
345         bfa_trc(port->fcs, event);
346
347         switch (event) {
348         case FDMISM_EVENT_TIMEOUT:
349                 /*
350                  * Retry Timer Expired. Re-send
351                  */
352                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt);
353                 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
354                 break;
355
356         case FDMISM_EVENT_PORT_OFFLINE:
357                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
358                 bfa_timer_stop(&fdmi->timer);
359                 break;
360
361         default:
362                 bfa_sm_fault(port->fcs, event);
363         }
364 }
365
366 /*
367  * Register Port Attributes
368  */
369 static void
370 bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
371                                  enum port_fdmi_event event)
372 {
373         struct bfa_fcs_port_s *port = fdmi->ms->port;
374
375         bfa_trc(port->fcs, port->port_cfg.pwwn);
376         bfa_trc(port->fcs, event);
377
378         switch (event) {
379         case FDMISM_EVENT_RPA_SENT:
380                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa);
381                 break;
382
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),
386                                        &fdmi->fcxp_wqe);
387                 break;
388
389         default:
390                 bfa_sm_fault(port->fcs, event);
391         }
392 }
393
394 static void
395 bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
396                          enum port_fdmi_event event)
397 {
398         struct bfa_fcs_port_s *port = fdmi->ms->port;
399
400         bfa_trc(port->fcs, port->port_cfg.pwwn);
401         bfa_trc(port->fcs, event);
402
403         switch (event) {
404         case FDMISM_EVENT_RSP_ERROR:
405                 /*
406                  * if max retries have not been reached, start timer for a
407                  * delayed retry
408                  */
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);
414                 } else {
415                         /*
416                          * set state to offline
417                          */
418                         bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
419                         fdmi->retry_cnt = 0;
420                 }
421                 break;
422
423         case FDMISM_EVENT_RSP_OK:
424                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
425                 fdmi->retry_cnt = 0;
426                 break;
427
428         case FDMISM_EVENT_PORT_OFFLINE:
429                 bfa_fcxp_discard(fdmi->fcxp);
430                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
431                 break;
432
433         default:
434                 bfa_sm_fault(port->fcs, event);
435         }
436 }
437
438 static void
439 bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
440                                enum port_fdmi_event event)
441 {
442         struct bfa_fcs_port_s *port = fdmi->ms->port;
443
444         bfa_trc(port->fcs, port->port_cfg.pwwn);
445         bfa_trc(port->fcs, event);
446
447         switch (event) {
448         case FDMISM_EVENT_TIMEOUT:
449                 /*
450                  * Retry Timer Expired. Re-send
451                  */
452                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
453                 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
454                 break;
455
456         case FDMISM_EVENT_PORT_OFFLINE:
457                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
458                 bfa_timer_stop(&fdmi->timer);
459                 break;
460
461         default:
462                 bfa_sm_fault(port->fcs, event);
463         }
464 }
465
466 static void
467 bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
468                             enum port_fdmi_event event)
469 {
470         struct bfa_fcs_port_s *port = fdmi->ms->port;
471
472         bfa_trc(port->fcs, port->port_cfg.pwwn);
473         bfa_trc(port->fcs, event);
474
475         switch (event) {
476         case FDMISM_EVENT_PORT_OFFLINE:
477                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
478                 break;
479
480         default:
481                 bfa_sm_fault(port->fcs, event);
482         }
483 }
484
485 /**
486  *  FDMI is disabled state.
487  */
488 static void
489 bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
490                                 enum port_fdmi_event event)
491 {
492         struct bfa_fcs_port_s *port = fdmi->ms->port;
493
494         bfa_trc(port->fcs, port->port_cfg.pwwn);
495         bfa_trc(port->fcs, event);
496
497         /* No op State. It can only be enabled at Driver Init. */
498 }
499
500 /**
501 *   RHBA : Register HBA Attributes.
502  */
503 static void
504 bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
505 {
506         struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
507         struct bfa_fcs_port_s *port = fdmi->ms->port;
508         struct fchs_s          fchs;
509         int             len, attr_len;
510         struct bfa_fcxp_s *fcxp;
511         u8        *pyld;
512
513         bfa_trc(port->fcs, port->port_cfg.pwwn);
514
515         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
516         if (!fcxp) {
517                 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
518                                     bfa_fcs_port_fdmi_send_rhba, fdmi);
519                 return;
520         }
521         fdmi->fcxp = fcxp;
522
523         pyld = bfa_fcxp_get_reqbuf(fcxp);
524         bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
525
526         len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
527                                    FDMI_RHBA);
528
529         attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi,
530                         (u8 *) ((struct ct_hdr_s *) pyld + 1));
531
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_FCCT_TOV);
536
537         bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
538 }
539
540 static          u16
541 bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
542                                   u8 *pyld)
543 {
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;
549         u8        *curr_ptr;
550         u16        len, count;
551
552         /*
553          * get hba attributes
554          */
555         bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
556
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);
560
561         len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
562
563         count = 0;
564         len += sizeof(rhba->hba_attr_blk.attr_count);
565
566         /*
567          * fill out the invididual entries of the HBA attrib Block
568          */
569         curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
570
571         /*
572          * Node Name
573          */
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;
579         len += attr->len;
580         count++;
581         attr->len =
582                 bfa_os_htons(attr->len + sizeof(attr->type) +
583                              sizeof(attr->len));
584
585         /*
586          * Manufacturer
587          */
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;
595         len += attr->len;
596         count++;
597         attr->len =
598                 bfa_os_htons(attr->len + sizeof(attr->type) +
599                              sizeof(attr->len));
600
601         /*
602          * Serial Number
603          */
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;
611         len += attr->len;
612         count++;
613         attr->len =
614                 bfa_os_htons(attr->len + sizeof(attr->type) +
615                              sizeof(attr->len));
616
617         /*
618          * Model
619          */
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;
627         len += attr->len;
628         count++;
629         attr->len =
630                 bfa_os_htons(attr->len + sizeof(attr->type) +
631                              sizeof(attr->len));
632
633         /*
634          * Model Desc
635          */
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;
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          * H/W Version
651          */
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;
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         /*
668          * Driver Version
669          */
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;
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          * Option Rom Version
685          */
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;
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         /*
702          * f/w Version = driver version
703          */
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;
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          * OS Name
719          */
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;
728                 len += attr->len;
729                 count++;
730                 attr->len =
731                         bfa_os_htons(attr->len + sizeof(attr->type) +
732                                      sizeof(attr->len));
733         }
734
735         /*
736          * MAX_CT_PAYLOAD
737          */
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);
742         len += attr->len;
743         count++;
744         attr->len =
745                 bfa_os_htons(attr->len + sizeof(attr->type) +
746                              sizeof(attr->len));
747
748         /*
749          * Update size of payload
750          */
751         len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
752
753         rhba->hba_attr_blk.attr_count = bfa_os_htonl(count);
754         return len;
755 }
756
757 static void
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)
762 {
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;
766
767         bfa_trc(port->fcs, port->port_cfg.pwwn);
768
769         /*
770          * Sanity Checks
771          */
772         if (req_status != BFA_STATUS_OK) {
773                 bfa_trc(port->fcs, req_status);
774                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
775                 return;
776         }
777
778         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
779         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
780
781         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
782                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
783                 return;
784         }
785
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);
789 }
790
791 /**
792 *   RPRT : Register Port
793  */
794 static void
795 bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
796 {
797         struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
798         struct bfa_fcs_port_s *port = fdmi->ms->port;
799         struct fchs_s          fchs;
800         u16        len, attr_len;
801         struct bfa_fcxp_s *fcxp;
802         u8        *pyld;
803
804         bfa_trc(port->fcs, port->port_cfg.pwwn);
805
806         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
807         if (!fcxp) {
808                 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
809                                     bfa_fcs_port_fdmi_send_rprt, fdmi);
810                 return;
811         }
812         fdmi->fcxp = fcxp;
813
814         pyld = bfa_fcxp_get_reqbuf(fcxp);
815         bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
816
817         len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
818                                    FDMI_RPRT);
819
820         attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi,
821                         (u8 *) ((struct ct_hdr_s *) pyld + 1));
822
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_FCCT_TOV);
827
828         bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
829 }
830
831 /**
832  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
833  */
834 static          u16
835 bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi,
836                                        u8 *pyld)
837 {
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;
841         u8        *curr_ptr;
842         u16        len;
843         u8         count = 0;
844
845         /*
846          * get port attributes
847          */
848         bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
849
850         len = sizeof(port_attrib->attr_count);
851
852         /*
853          * fill out the invididual entries
854          */
855         curr_ptr = (u8 *) &port_attrib->port_attr;
856
857         /*
858          * FC4 Types
859          */
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;
865         len += attr->len;
866         ++count;
867         attr->len =
868                 bfa_os_htons(attr->len + sizeof(attr->type) +
869                              sizeof(attr->len));
870
871         /*
872          * Supported Speed
873          */
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;
879         len += attr->len;
880         ++count;
881         attr->len =
882                 bfa_os_htons(attr->len + sizeof(attr->type) +
883                              sizeof(attr->len));
884
885         /*
886          * current Port Speed
887          */
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;
893         len += attr->len;
894         ++count;
895         attr->len =
896                 bfa_os_htons(attr->len + sizeof(attr->type) +
897                              sizeof(attr->len));
898
899         /*
900          * max frame size
901          */
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;
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          * OS Device Name
915          */
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;
924                 len += attr->len;
925                 ++count;
926                 attr->len =
927                         bfa_os_htons(attr->len + sizeof(attr->type) +
928                                      sizeof(attr->len));
929
930         }
931         /*
932          * Host Name
933          */
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;
942                 len += attr->len;
943                 ++count;
944                 attr->len =
945                         bfa_os_htons(attr->len + sizeof(attr->type) +
946                                      sizeof(attr->len));
947
948         }
949
950         /*
951          * Update size of payload
952          */
953         port_attrib->attr_count = bfa_os_htonl(count);
954         len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
955         return len;
956 }
957
958 static          u16
959 bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
960                                   u8 *pyld)
961 {
962         struct bfa_fcs_port_s *port = fdmi->ms->port;
963         struct fdmi_rprt_s    *rprt = (struct fdmi_rprt_s *) pyld;
964         u16        len;
965
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);
968
969         len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
970                         (u8 *) &rprt->port_attr_blk);
971
972         len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
973
974         return len;
975 }
976
977 static void
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)
982 {
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;
986
987         bfa_trc(port->fcs, port->port_cfg.pwwn);
988
989         /*
990          * Sanity Checks
991          */
992         if (req_status != BFA_STATUS_OK) {
993                 bfa_trc(port->fcs, req_status);
994                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
995                 return;
996         }
997
998         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
999         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1000
1001         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1002                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1003                 return;
1004         }
1005
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);
1009 }
1010
1011 /**
1012 *   RPA : Register Port Attributes.
1013  */
1014 static void
1015 bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1016 {
1017         struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
1018         struct bfa_fcs_port_s *port = fdmi->ms->port;
1019         struct fchs_s          fchs;
1020         u16        len, attr_len;
1021         struct bfa_fcxp_s *fcxp;
1022         u8        *pyld;
1023
1024         bfa_trc(port->fcs, port->port_cfg.pwwn);
1025
1026         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1027         if (!fcxp) {
1028                 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1029                                     bfa_fcs_port_fdmi_send_rpa, fdmi);
1030                 return;
1031         }
1032         fdmi->fcxp = fcxp;
1033
1034         pyld = bfa_fcxp_get_reqbuf(fcxp);
1035         bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
1036
1037         len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
1038                                    FDMI_RPA);
1039
1040         attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi,
1041                         (u8 *) ((struct ct_hdr_s *) pyld + 1));
1042
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_FCCT_TOV);
1047
1048         bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
1049 }
1050
1051 static          u16
1052 bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
1053                                  u8 *pyld)
1054 {
1055         struct bfa_fcs_port_s *port = fdmi->ms->port;
1056         struct fdmi_rpa_s     *rpa = (struct fdmi_rpa_s *) pyld;
1057         u16        len;
1058
1059         rpa->port_name = bfa_fcs_port_get_pwwn(port);
1060
1061         len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
1062                         (u8 *) &rpa->port_attr_blk);
1063
1064         len += sizeof(rpa->port_name);
1065
1066         return len;
1067 }
1068
1069 static void
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)
1074 {
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;
1078
1079         bfa_trc(port->fcs, port->port_cfg.pwwn);
1080
1081         /*
1082          * Sanity Checks
1083          */
1084         if (req_status != BFA_STATUS_OK) {
1085                 bfa_trc(port->fcs, req_status);
1086                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1087                 return;
1088         }
1089
1090         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1091         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1092
1093         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1094                 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1095                 return;
1096         }
1097
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);
1101 }
1102
1103 static void
1104 bfa_fcs_port_fdmi_timeout(void *arg)
1105 {
1106         struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg;
1107
1108         bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
1109 }
1110
1111 static void
1112 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
1113                          struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
1114 {
1115         struct bfa_fcs_port_s *port = fdmi->ms->port;
1116         struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
1117
1118         bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
1119
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);
1130
1131         strncpy(hba_attr->driver_version, (char *)driver_info->version,
1132                 sizeof(hba_attr->driver_version));
1133
1134         strncpy(hba_attr->os_name, driver_info->host_os_name,
1135                 sizeof(hba_attr->os_name));
1136
1137         /*
1138          * If there is a patch level, append it to the os name along with a
1139          * separator
1140          */
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));
1146         }
1147
1148         hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ);
1149
1150 }
1151
1152 static void
1153 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
1154                           struct bfa_fcs_fdmi_port_attr_s *port_attr)
1155 {
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;
1159
1160         bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
1161
1162         /*
1163          * get pport attributes from hal
1164          */
1165         bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
1166
1167         /*
1168          * get FC4 type Bitmask
1169          */
1170         fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
1171
1172         /*
1173          * Supported Speeds
1174          */
1175         port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS);
1176
1177         /*
1178          * Current Speed
1179          */
1180         port_attr->curr_speed = bfa_os_htonl(pport_attr.speed);
1181
1182         /*
1183          * Max PDU Size.
1184          */
1185         port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ);
1186
1187         /*
1188          * OS device Name
1189          */
1190         strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
1191                 sizeof(port_attr->os_device_name));
1192
1193         /*
1194          * Host name
1195          */
1196         strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
1197                 sizeof(port_attr->host_name));
1198
1199 }
1200
1201
1202 void
1203 bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
1204 {
1205         struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1206
1207         fdmi->ms = ms;
1208         if (ms->port->fcs->fdmi_enabled)
1209                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
1210         else
1211                 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled);
1212 }
1213
1214 void
1215 bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms)
1216 {
1217         struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1218
1219         fdmi->ms = ms;
1220         bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
1221 }
1222
1223 void
1224 bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms)
1225 {
1226         struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1227
1228         fdmi->ms = ms;
1229         bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
1230 }