• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/scsi/bfa/
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
32BFA_TRC_FILE(FCS, FDMI);
33
34#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
35
36/*
37 * forward declarations
38 */
39static void     bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg,
40					    struct bfa_fcxp_s *fcxp_alloced);
41static void     bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg,
42					    struct bfa_fcxp_s *fcxp_alloced);
43static void     bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg,
44					   struct bfa_fcxp_s *fcxp_alloced);
45static 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);
52static 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);
59static 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);
66static void     bfa_fcs_port_fdmi_timeout(void *arg);
67static u16 bfa_fcs_port_fdmi_build_rhba_pyld(
68			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
69static u16 bfa_fcs_port_fdmi_build_rprt_pyld(
70			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
71static u16 bfa_fcs_port_fdmi_build_rpa_pyld(
72			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
73static u16 bfa_fcs_port_fdmi_build_portattr_block(
74			struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
75static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
76			struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
77static 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 */
86enum 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
97static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
98			enum port_fdmi_event event);
99static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
100			enum port_fdmi_event event);
101static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
102			enum port_fdmi_event event);
103static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
104			enum port_fdmi_event event);
105static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
106			enum port_fdmi_event event);
107static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
108			enum port_fdmi_event event);
109static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
110			enum port_fdmi_event event);
111static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
112			enum port_fdmi_event event);
113static void     bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
114			enum port_fdmi_event event);
115static void     bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
116			enum port_fdmi_event event);
117static void     bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
118			enum port_fdmi_event event);
119static 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 */
125static void
126bfa_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
165static void
166bfa_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
190static void
191bfa_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
237static void
238bfa_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 */
268static void
269bfa_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
293static void
294bfa_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
338static void
339bfa_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 */
369static void
370bfa_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
394static void
395bfa_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
438static void
439bfa_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
466static void
467bfa_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 */
488static void
489bfa_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 */
503static void
504bfa_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
540static          u16
541bfa_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
757static void
758bfa_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 */
794static void
795bfa_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 */
834static          u16
835bfa_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
958static          u16
959bfa_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
977static void
978bfa_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 */
1014static void
1015bfa_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
1051static          u16
1052bfa_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
1069static void
1070bfa_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
1103static void
1104bfa_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
1111static void
1112bfa_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
1152static void
1153bfa_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
1202void
1203bfa_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
1214void
1215bfa_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
1223void
1224bfa_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}
1231