• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/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#include <bfa.h>
19#include <bfa_svc.h>
20#include <bfi/bfi_pport.h>
21#include <bfi/bfi_pbc.h>
22#include <cs/bfa_debug.h>
23#include <aen/bfa_aen.h>
24#include <cs/bfa_plog.h>
25#include <aen/bfa_aen_port.h>
26
27BFA_TRC_FILE(HAL, FCPORT);
28BFA_MODULE(fcport);
29
30/*
31 * The port is considered disabled if corresponding physical port or IOC are
32 * disabled explicitly
33 */
34#define BFA_PORT_IS_DISABLED(bfa) \
35	((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
36	(bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
37
38/*
39 * forward declarations
40 */
41static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
42static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
43static void     bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
44static void     bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
45static void     bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
46static void     __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
47static void     bfa_fcport_callback(struct bfa_fcport_s *fcport,
48				enum bfa_pport_linkstate event);
49static void     bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
50				enum bfa_pport_linkstate event);
51static void     __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
52static void     bfa_fcport_stats_get_timeout(void *cbarg);
53static void     bfa_fcport_stats_clr_timeout(void *cbarg);
54
55/**
56 *  bfa_pport_private
57 */
58
59/**
60 * BFA port state machine events
61 */
62enum bfa_fcport_sm_event {
63	BFA_FCPORT_SM_START = 1,	/*  start port state machine */
64	BFA_FCPORT_SM_STOP = 2,	/*  stop port state machine */
65	BFA_FCPORT_SM_ENABLE = 3,	/*  enable port */
66	BFA_FCPORT_SM_DISABLE = 4,	/*  disable port state machine */
67	BFA_FCPORT_SM_FWRSP = 5,	/*  firmware enable/disable rsp */
68	BFA_FCPORT_SM_LINKUP = 6,	/*  firmware linkup event */
69	BFA_FCPORT_SM_LINKDOWN = 7,	/*  firmware linkup down */
70	BFA_FCPORT_SM_QRESUME = 8,	/*  CQ space available */
71	BFA_FCPORT_SM_HWFAIL = 9,	/*  IOC h/w failure */
72};
73
74/**
75 * BFA port link notification state machine events
76 */
77
78enum bfa_fcport_ln_sm_event {
79	BFA_FCPORT_LN_SM_LINKUP         = 1,    /*  linkup event */
80	BFA_FCPORT_LN_SM_LINKDOWN       = 2,    /*  linkdown event */
81	BFA_FCPORT_LN_SM_NOTIFICATION   = 3     /*  done notification */
82};
83
84static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
85					enum bfa_fcport_sm_event event);
86static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
87						enum bfa_fcport_sm_event event);
88static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
89						enum bfa_fcport_sm_event event);
90static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
91						enum bfa_fcport_sm_event event);
92static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
93						enum bfa_fcport_sm_event event);
94static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
95						enum bfa_fcport_sm_event event);
96static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
97						enum bfa_fcport_sm_event event);
98static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
99						enum bfa_fcport_sm_event event);
100static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
101					 enum bfa_fcport_sm_event event);
102static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
103					 enum bfa_fcport_sm_event event);
104static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
105					 enum bfa_fcport_sm_event event);
106
107static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
108					 enum bfa_fcport_ln_sm_event event);
109static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
110					 enum bfa_fcport_ln_sm_event event);
111static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
112					 enum bfa_fcport_ln_sm_event event);
113static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
114					 enum bfa_fcport_ln_sm_event event);
115static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
116					 enum bfa_fcport_ln_sm_event event);
117static void     bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
118					 enum bfa_fcport_ln_sm_event event);
119static void     bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
120					 enum bfa_fcport_ln_sm_event event);
121
122static struct bfa_sm_table_s hal_pport_sm_table[] = {
123	{BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
124	{BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
125	{BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
126	{BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
127	{BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
128	{BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
129	{BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
130	{BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
131	{BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
132	{BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
133	{BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
134};
135
136static void
137bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
138{
139	union bfa_aen_data_u aen_data;
140	struct bfa_log_mod_s *logmod = fcport->bfa->logm;
141	wwn_t           pwwn = fcport->pwwn;
142	char            pwwn_ptr[BFA_STRING_32];
143
144	memset(&aen_data, 0, sizeof(aen_data));
145	wwn2str(pwwn_ptr, pwwn);
146	bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
147
148	aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
149	aen_data.port.pwwn = pwwn;
150}
151
152static void
153bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
154			enum bfa_fcport_sm_event event)
155{
156	bfa_trc(fcport->bfa, event);
157
158	switch (event) {
159	case BFA_FCPORT_SM_START:
160		/**
161		 * Start event after IOC is configured and BFA is started.
162		 */
163		if (bfa_fcport_send_enable(fcport))
164			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
165		else
166			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
167		break;
168
169	case BFA_FCPORT_SM_ENABLE:
170		/**
171		 * Port is persistently configured to be in enabled state. Do
172		 * not change state. Port enabling is done when START event is
173		 * received.
174		 */
175		break;
176
177	case BFA_FCPORT_SM_DISABLE:
178		/**
179		 * If a port is persistently configured to be disabled, the
180		 * first event will a port disable request.
181		 */
182		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
183		break;
184
185	case BFA_FCPORT_SM_HWFAIL:
186		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
187		break;
188
189	default:
190		bfa_sm_fault(fcport->bfa, event);
191	}
192}
193
194static void
195bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
196			    enum bfa_fcport_sm_event event)
197{
198	bfa_trc(fcport->bfa, event);
199
200	switch (event) {
201	case BFA_FCPORT_SM_QRESUME:
202		bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
203		bfa_fcport_send_enable(fcport);
204		break;
205
206	case BFA_FCPORT_SM_STOP:
207		bfa_reqq_wcancel(&fcport->reqq_wait);
208		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
209		break;
210
211	case BFA_FCPORT_SM_ENABLE:
212		/**
213		 * Already enable is in progress.
214		 */
215		break;
216
217	case BFA_FCPORT_SM_DISABLE:
218		/**
219		 * Just send disable request to firmware when room becomes
220		 * available in request queue.
221		 */
222		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
223		bfa_reqq_wcancel(&fcport->reqq_wait);
224		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
225			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
226		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
227		break;
228
229	case BFA_FCPORT_SM_LINKUP:
230	case BFA_FCPORT_SM_LINKDOWN:
231		/**
232		 * Possible to get link events when doing back-to-back
233		 * enable/disables.
234		 */
235		break;
236
237	case BFA_FCPORT_SM_HWFAIL:
238		bfa_reqq_wcancel(&fcport->reqq_wait);
239		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
240		break;
241
242	default:
243		bfa_sm_fault(fcport->bfa, event);
244	}
245}
246
247static void
248bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
249		enum bfa_fcport_sm_event event)
250{
251	bfa_trc(fcport->bfa, event);
252
253	switch (event) {
254	case BFA_FCPORT_SM_FWRSP:
255	case BFA_FCPORT_SM_LINKDOWN:
256		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
257		break;
258
259	case BFA_FCPORT_SM_LINKUP:
260		bfa_fcport_update_linkinfo(fcport);
261		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
262
263		bfa_assert(fcport->event_cbfn);
264		bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
265		break;
266
267	case BFA_FCPORT_SM_ENABLE:
268		/**
269		 * Already being enabled.
270		 */
271		break;
272
273	case BFA_FCPORT_SM_DISABLE:
274		if (bfa_fcport_send_disable(fcport))
275			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
276		else
277			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
278
279		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
280			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
281		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
282		break;
283
284	case BFA_FCPORT_SM_STOP:
285		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
286		break;
287
288	case BFA_FCPORT_SM_HWFAIL:
289		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
290		break;
291
292	default:
293		bfa_sm_fault(fcport->bfa, event);
294	}
295}
296
297static void
298bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
299			enum bfa_fcport_sm_event event)
300{
301	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
302	bfa_trc(fcport->bfa, event);
303
304	switch (event) {
305	case BFA_FCPORT_SM_LINKUP:
306		bfa_fcport_update_linkinfo(fcport);
307		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
308		bfa_assert(fcport->event_cbfn);
309		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
310			     BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
311
312		if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
313
314			bfa_trc(fcport->bfa,
315				pevent->link_state.vc_fcf.fcf.fipenabled);
316			bfa_trc(fcport->bfa,
317				pevent->link_state.vc_fcf.fcf.fipfailed);
318
319			if (pevent->link_state.vc_fcf.fcf.fipfailed)
320				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
321					BFA_PL_EID_FIP_FCF_DISC, 0,
322					"FIP FCF Discovery Failed");
323			else
324				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
325					BFA_PL_EID_FIP_FCF_DISC, 0,
326					"FIP FCF Discovered");
327		}
328
329		bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
330		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
331		/**
332		 * If QoS is enabled and it is not online,
333		 * Send a separate event.
334		 */
335		if ((fcport->cfg.qos_enabled)
336		    && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
337			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
338
339		break;
340
341	case BFA_FCPORT_SM_LINKDOWN:
342		/**
343		 * Possible to get link down event.
344		 */
345		break;
346
347	case BFA_FCPORT_SM_ENABLE:
348		/**
349		 * Already enabled.
350		 */
351		break;
352
353	case BFA_FCPORT_SM_DISABLE:
354		if (bfa_fcport_send_disable(fcport))
355			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
356		else
357			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
358
359		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
360			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
361		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
362		break;
363
364	case BFA_FCPORT_SM_STOP:
365		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
366		break;
367
368	case BFA_FCPORT_SM_HWFAIL:
369		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
370		break;
371
372	default:
373		bfa_sm_fault(fcport->bfa, event);
374	}
375}
376
377static void
378bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
379			enum bfa_fcport_sm_event event)
380{
381	bfa_trc(fcport->bfa, event);
382
383	switch (event) {
384	case BFA_FCPORT_SM_ENABLE:
385		/**
386		 * Already enabled.
387		 */
388		break;
389
390	case BFA_FCPORT_SM_DISABLE:
391		if (bfa_fcport_send_disable(fcport))
392			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
393		else
394			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
395
396		bfa_fcport_reset_linkinfo(fcport);
397		bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
398		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
399			     BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
400		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
401		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
402		break;
403
404	case BFA_FCPORT_SM_LINKDOWN:
405		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
406		bfa_fcport_reset_linkinfo(fcport);
407		bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
408		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
409			     BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
410		if (BFA_PORT_IS_DISABLED(fcport->bfa))
411			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
412		else
413			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
414		break;
415
416	case BFA_FCPORT_SM_STOP:
417		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
418		bfa_fcport_reset_linkinfo(fcport);
419		if (BFA_PORT_IS_DISABLED(fcport->bfa))
420			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
421		else
422			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
423		break;
424
425	case BFA_FCPORT_SM_HWFAIL:
426		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
427		bfa_fcport_reset_linkinfo(fcport);
428		bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
429		if (BFA_PORT_IS_DISABLED(fcport->bfa))
430			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
431		else
432			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
433		break;
434
435	default:
436		bfa_sm_fault(fcport->bfa, event);
437	}
438}
439
440static void
441bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
442			     enum bfa_fcport_sm_event event)
443{
444	bfa_trc(fcport->bfa, event);
445
446	switch (event) {
447	case BFA_FCPORT_SM_QRESUME:
448		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
449		bfa_fcport_send_disable(fcport);
450		break;
451
452	case BFA_FCPORT_SM_STOP:
453		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
454		bfa_reqq_wcancel(&fcport->reqq_wait);
455		break;
456
457	case BFA_FCPORT_SM_DISABLE:
458		/**
459		 * Already being disabled.
460		 */
461		break;
462
463	case BFA_FCPORT_SM_LINKUP:
464	case BFA_FCPORT_SM_LINKDOWN:
465		/**
466		 * Possible to get link events when doing back-to-back
467		 * enable/disables.
468		 */
469		break;
470
471	case BFA_FCPORT_SM_HWFAIL:
472		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
473		bfa_reqq_wcancel(&fcport->reqq_wait);
474		break;
475
476	default:
477		bfa_sm_fault(fcport->bfa, event);
478	}
479}
480
481static void
482bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
483			enum bfa_fcport_sm_event event)
484{
485	bfa_trc(fcport->bfa, event);
486
487	switch (event) {
488	case BFA_FCPORT_SM_FWRSP:
489		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
490		break;
491
492	case BFA_FCPORT_SM_DISABLE:
493		/**
494		 * Already being disabled.
495		 */
496		break;
497
498	case BFA_FCPORT_SM_ENABLE:
499		if (bfa_fcport_send_enable(fcport))
500			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
501		else
502			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
503
504		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
505			     BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
506		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
507		break;
508
509	case BFA_FCPORT_SM_STOP:
510		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
511		break;
512
513	case BFA_FCPORT_SM_LINKUP:
514	case BFA_FCPORT_SM_LINKDOWN:
515		/**
516		 * Possible to get link events when doing back-to-back
517		 * enable/disables.
518		 */
519		break;
520
521	case BFA_FCPORT_SM_HWFAIL:
522		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
523		break;
524
525	default:
526		bfa_sm_fault(fcport->bfa, event);
527	}
528}
529
530static void
531bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
532			enum bfa_fcport_sm_event event)
533{
534	bfa_trc(fcport->bfa, event);
535
536	switch (event) {
537	case BFA_FCPORT_SM_START:
538		/**
539		 * Ignore start event for a port that is disabled.
540		 */
541		break;
542
543	case BFA_FCPORT_SM_STOP:
544		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
545		break;
546
547	case BFA_FCPORT_SM_ENABLE:
548		if (bfa_fcport_send_enable(fcport))
549			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
550		else
551			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
552
553		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
554			     BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
555		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
556		break;
557
558	case BFA_FCPORT_SM_DISABLE:
559		/**
560		 * Already disabled.
561		 */
562		break;
563
564	case BFA_FCPORT_SM_HWFAIL:
565		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
566		break;
567
568	default:
569		bfa_sm_fault(fcport->bfa, event);
570	}
571}
572
573static void
574bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
575			enum bfa_fcport_sm_event event)
576{
577	bfa_trc(fcport->bfa, event);
578
579	switch (event) {
580	case BFA_FCPORT_SM_START:
581		if (bfa_fcport_send_enable(fcport))
582			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
583		else
584			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
585		break;
586
587	default:
588		/**
589		 * Ignore all other events.
590		 */
591		;
592	}
593}
594
595/**
596 * Port is enabled. IOC is down/failed.
597 */
598static void
599bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
600			enum bfa_fcport_sm_event event)
601{
602	bfa_trc(fcport->bfa, event);
603
604	switch (event) {
605	case BFA_FCPORT_SM_START:
606		if (bfa_fcport_send_enable(fcport))
607			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
608		else
609			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
610		break;
611
612	default:
613		/**
614		 * Ignore all events.
615		 */
616		;
617	}
618}
619
620/**
621 * Port is disabled. IOC is down/failed.
622 */
623static void
624bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
625			enum bfa_fcport_sm_event event)
626{
627	bfa_trc(fcport->bfa, event);
628
629	switch (event) {
630	case BFA_FCPORT_SM_START:
631		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
632		break;
633
634	case BFA_FCPORT_SM_ENABLE:
635		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
636		break;
637
638	default:
639		/**
640		 * Ignore all events.
641		 */
642		;
643	}
644}
645
646/**
647 * Link state is down
648 */
649static void
650bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
651		enum bfa_fcport_ln_sm_event event)
652{
653	bfa_trc(ln->fcport->bfa, event);
654
655	switch (event) {
656	case BFA_FCPORT_LN_SM_LINKUP:
657		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
658		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
659		break;
660
661	default:
662		bfa_sm_fault(ln->fcport->bfa, event);
663	}
664}
665
666/**
667 * Link state is waiting for down notification
668 */
669static void
670bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
671		enum bfa_fcport_ln_sm_event event)
672{
673	bfa_trc(ln->fcport->bfa, event);
674
675	switch (event) {
676	case BFA_FCPORT_LN_SM_LINKUP:
677		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
678		break;
679
680	case BFA_FCPORT_LN_SM_NOTIFICATION:
681		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
682		break;
683
684	default:
685		bfa_sm_fault(ln->fcport->bfa, event);
686	}
687}
688
689/**
690 * Link state is waiting for down notification and there is a pending up
691 */
692static void
693bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
694		enum bfa_fcport_ln_sm_event event)
695{
696	bfa_trc(ln->fcport->bfa, event);
697
698	switch (event) {
699	case BFA_FCPORT_LN_SM_LINKDOWN:
700		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
701		break;
702
703	case BFA_FCPORT_LN_SM_NOTIFICATION:
704		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
705		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
706		break;
707
708	default:
709		bfa_sm_fault(ln->fcport->bfa, event);
710	}
711}
712
713/**
714 * Link state is up
715 */
716static void
717bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
718		enum bfa_fcport_ln_sm_event event)
719{
720	bfa_trc(ln->fcport->bfa, event);
721
722	switch (event) {
723	case BFA_FCPORT_LN_SM_LINKDOWN:
724		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
725		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
726		break;
727
728	default:
729		bfa_sm_fault(ln->fcport->bfa, event);
730	}
731}
732
733/**
734 * Link state is waiting for up notification
735 */
736static void
737bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
738		enum bfa_fcport_ln_sm_event event)
739{
740	bfa_trc(ln->fcport->bfa, event);
741
742	switch (event) {
743	case BFA_FCPORT_LN_SM_LINKDOWN:
744		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
745		break;
746
747	case BFA_FCPORT_LN_SM_NOTIFICATION:
748		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
749		break;
750
751	default:
752		bfa_sm_fault(ln->fcport->bfa, event);
753	}
754}
755
756/**
757 * Link state is waiting for up notification and there is a pending down
758 */
759static void
760bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
761		enum bfa_fcport_ln_sm_event event)
762{
763	bfa_trc(ln->fcport->bfa, event);
764
765	switch (event) {
766	case BFA_FCPORT_LN_SM_LINKUP:
767		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
768		break;
769
770	case BFA_FCPORT_LN_SM_NOTIFICATION:
771		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
772		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
773		break;
774
775	default:
776		bfa_sm_fault(ln->fcport->bfa, event);
777	}
778}
779
780/**
781 * Link state is waiting for up notification and there are pending down and up
782 */
783static void
784bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
785			enum bfa_fcport_ln_sm_event event)
786{
787	bfa_trc(ln->fcport->bfa, event);
788
789	switch (event) {
790	case BFA_FCPORT_LN_SM_LINKDOWN:
791		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
792		break;
793
794	case BFA_FCPORT_LN_SM_NOTIFICATION:
795		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
796		bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
797		break;
798
799	default:
800		bfa_sm_fault(ln->fcport->bfa, event);
801	}
802}
803
804/**
805 *  bfa_pport_private
806 */
807
808static void
809__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
810{
811	struct bfa_fcport_ln_s *ln = cbarg;
812
813	if (complete)
814		ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
815	else
816		bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
817}
818
819static void
820bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
821{
822	if (fcport->bfa->fcs) {
823		fcport->event_cbfn(fcport->event_cbarg, event);
824		return;
825	}
826
827	switch (event) {
828	case BFA_PPORT_LINKUP:
829		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
830		break;
831	case BFA_PPORT_LINKDOWN:
832		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
833		break;
834	default:
835		bfa_assert(0);
836	}
837}
838
839static void
840bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
841{
842	ln->ln_event = event;
843	bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
844}
845
846#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
847							BFA_CACHELINE_SZ))
848
849static void
850bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
851		  u32 *dm_len)
852{
853	*dm_len += FCPORT_STATS_DMA_SZ;
854}
855
856static void
857bfa_fcport_qresume(void *cbarg)
858{
859	struct bfa_fcport_s *fcport = cbarg;
860
861	bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
862}
863
864static void
865bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
866{
867	u8        *dm_kva;
868	u64        dm_pa;
869
870	dm_kva = bfa_meminfo_dma_virt(meminfo);
871	dm_pa = bfa_meminfo_dma_phys(meminfo);
872
873	fcport->stats_kva = dm_kva;
874	fcport->stats_pa = dm_pa;
875	fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
876
877	dm_kva += FCPORT_STATS_DMA_SZ;
878	dm_pa += FCPORT_STATS_DMA_SZ;
879
880	bfa_meminfo_dma_virt(meminfo) = dm_kva;
881	bfa_meminfo_dma_phys(meminfo) = dm_pa;
882}
883
884/**
885 * Memory initialization.
886 */
887static void
888bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
889		 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
890{
891	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
892	struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
893	struct bfa_fcport_ln_s *ln = &fcport->ln;
894	struct bfa_timeval_s tv;
895
896	bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
897	fcport->bfa = bfa;
898	ln->fcport = fcport;
899
900	bfa_fcport_mem_claim(fcport, meminfo);
901
902	bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
903	bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
904
905	/**
906	 * initialize time stamp for stats reset
907	 */
908	bfa_os_gettimeofday(&tv);
909	fcport->stats_reset_time = tv.tv_sec;
910
911	/**
912	 * initialize and set default configuration
913	 */
914	port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
915	port_cfg->speed = BFA_PPORT_SPEED_AUTO;
916	port_cfg->trunked = BFA_FALSE;
917	port_cfg->maxfrsize = 0;
918
919	port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
920
921	bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
922}
923
924static void
925bfa_fcport_detach(struct bfa_s *bfa)
926{
927}
928
929/**
930 * Called when IOC is ready.
931 */
932static void
933bfa_fcport_start(struct bfa_s *bfa)
934{
935	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
936}
937
938/**
939 * Called before IOC is stopped.
940 */
941static void
942bfa_fcport_stop(struct bfa_s *bfa)
943{
944	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
945}
946
947/**
948 * Called when IOC failure is detected.
949 */
950static void
951bfa_fcport_iocdisable(struct bfa_s *bfa)
952{
953	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
954}
955
956static void
957bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
958{
959	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
960
961	fcport->speed = pevent->link_state.speed;
962	fcport->topology = pevent->link_state.topology;
963
964	if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
965		fcport->myalpa = 0;
966
967	/*
968	 * QoS Details
969	 */
970	bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
971	bfa_os_assign(fcport->qos_vc_attr,
972		pevent->link_state.vc_fcf.qos_vc_attr);
973
974
975	bfa_trc(fcport->bfa, fcport->speed);
976	bfa_trc(fcport->bfa, fcport->topology);
977}
978
979static void
980bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
981{
982	fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
983	fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
984}
985
986/**
987 * Send port enable message to firmware.
988 */
989static          bfa_boolean_t
990bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
991{
992	struct bfi_fcport_enable_req_s *m;
993
994	/**
995	 * Increment message tag before queue check, so that responses to old
996	 * requests are discarded.
997	 */
998	fcport->msgtag++;
999
1000	/**
1001	 * check for room in queue to send request now
1002	 */
1003	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1004	if (!m) {
1005		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1006							&fcport->reqq_wait);
1007		return BFA_FALSE;
1008	}
1009
1010	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
1011				bfa_lpuid(fcport->bfa));
1012	m->nwwn = fcport->nwwn;
1013	m->pwwn = fcport->pwwn;
1014	m->port_cfg = fcport->cfg;
1015	m->msgtag = fcport->msgtag;
1016	m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
1017	bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
1018	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
1019	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
1020
1021	/**
1022	 * queue I/O message to firmware
1023	 */
1024	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1025	return BFA_TRUE;
1026}
1027
1028/**
1029 * Send port disable message to firmware.
1030 */
1031static          bfa_boolean_t
1032bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
1033{
1034	struct bfi_fcport_req_s *m;
1035
1036	/**
1037	 * Increment message tag before queue check, so that responses to old
1038	 * requests are discarded.
1039	 */
1040	fcport->msgtag++;
1041
1042	/**
1043	 * check for room in queue to send request now
1044	 */
1045	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1046	if (!m) {
1047		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1048							&fcport->reqq_wait);
1049		return BFA_FALSE;
1050	}
1051
1052	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
1053			bfa_lpuid(fcport->bfa));
1054	m->msgtag = fcport->msgtag;
1055
1056	/**
1057	 * queue I/O message to firmware
1058	 */
1059	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1060
1061	return BFA_TRUE;
1062}
1063
1064static void
1065bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
1066{
1067	fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
1068	fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
1069
1070	bfa_trc(fcport->bfa, fcport->pwwn);
1071	bfa_trc(fcport->bfa, fcport->nwwn);
1072}
1073
1074static void
1075bfa_fcport_send_txcredit(void *port_cbarg)
1076{
1077
1078	struct bfa_fcport_s *fcport = port_cbarg;
1079	struct bfi_fcport_set_svc_params_req_s *m;
1080
1081	/**
1082	 * check for room in queue to send request now
1083	 */
1084	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1085	if (!m) {
1086		bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
1087		return;
1088	}
1089
1090	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
1091			bfa_lpuid(fcport->bfa));
1092	m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
1093
1094	/**
1095	 * queue I/O message to firmware
1096	 */
1097	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1098}
1099
1100static void
1101bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
1102	struct bfa_qos_stats_s *s)
1103{
1104	u32     *dip = (u32 *) d;
1105	u32     *sip = (u32 *) s;
1106	int             i;
1107
1108	/* Now swap the 32 bit fields */
1109	for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
1110		dip[i] = bfa_os_ntohl(sip[i]);
1111}
1112
1113static void
1114bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
1115	struct bfa_fcoe_stats_s *s)
1116{
1117	u32     *dip = (u32 *) d;
1118	u32     *sip = (u32 *) s;
1119	int             i;
1120
1121	for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
1122		i = i + 2) {
1123#ifdef __BIGENDIAN
1124		dip[i] = bfa_os_ntohl(sip[i]);
1125		dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1126#else
1127		dip[i] = bfa_os_ntohl(sip[i + 1]);
1128		dip[i + 1] = bfa_os_ntohl(sip[i]);
1129#endif
1130	}
1131}
1132
1133static void
1134__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
1135{
1136	struct bfa_fcport_s *fcport = cbarg;
1137
1138	if (complete) {
1139		if (fcport->stats_status == BFA_STATUS_OK) {
1140			struct bfa_timeval_s tv;
1141
1142			/* Swap FC QoS or FCoE stats */
1143			if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
1144				bfa_fcport_qos_stats_swap(
1145					&fcport->stats_ret->fcqos,
1146					&fcport->stats->fcqos);
1147			} else {
1148				bfa_fcport_fcoe_stats_swap(
1149					&fcport->stats_ret->fcoe,
1150					&fcport->stats->fcoe);
1151
1152				bfa_os_gettimeofday(&tv);
1153				fcport->stats_ret->fcoe.secs_reset =
1154					tv.tv_sec - fcport->stats_reset_time;
1155			}
1156		}
1157		fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
1158	} else {
1159		fcport->stats_busy = BFA_FALSE;
1160		fcport->stats_status = BFA_STATUS_OK;
1161	}
1162}
1163
1164static void
1165bfa_fcport_stats_get_timeout(void *cbarg)
1166{
1167	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1168
1169	bfa_trc(fcport->bfa, fcport->stats_qfull);
1170
1171	if (fcport->stats_qfull) {
1172		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
1173		fcport->stats_qfull = BFA_FALSE;
1174	}
1175
1176	fcport->stats_status = BFA_STATUS_ETIMER;
1177	bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
1178		fcport);
1179}
1180
1181static void
1182bfa_fcport_send_stats_get(void *cbarg)
1183{
1184	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1185	struct bfi_fcport_req_s *msg;
1186
1187	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1188
1189	if (!msg) {
1190		fcport->stats_qfull = BFA_TRUE;
1191		bfa_reqq_winit(&fcport->stats_reqq_wait,
1192				bfa_fcport_send_stats_get, fcport);
1193		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1194				&fcport->stats_reqq_wait);
1195		return;
1196	}
1197	fcport->stats_qfull = BFA_FALSE;
1198
1199	bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
1200	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
1201		bfa_lpuid(fcport->bfa));
1202	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1203}
1204
1205static void
1206__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
1207{
1208	struct bfa_fcport_s *fcport = cbarg;
1209
1210	if (complete) {
1211		struct bfa_timeval_s tv;
1212
1213		/**
1214		 * re-initialize time stamp for stats reset
1215		 */
1216		bfa_os_gettimeofday(&tv);
1217		fcport->stats_reset_time = tv.tv_sec;
1218
1219		fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
1220	} else {
1221		fcport->stats_busy = BFA_FALSE;
1222		fcport->stats_status = BFA_STATUS_OK;
1223	}
1224}
1225
1226static void
1227bfa_fcport_stats_clr_timeout(void *cbarg)
1228{
1229	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1230
1231	bfa_trc(fcport->bfa, fcport->stats_qfull);
1232
1233	if (fcport->stats_qfull) {
1234		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
1235		fcport->stats_qfull = BFA_FALSE;
1236	}
1237
1238	fcport->stats_status = BFA_STATUS_ETIMER;
1239	bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1240			__bfa_cb_fcport_stats_clr, fcport);
1241}
1242
1243static void
1244bfa_fcport_send_stats_clear(void *cbarg)
1245{
1246	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
1247	struct bfi_fcport_req_s *msg;
1248
1249	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
1250
1251	if (!msg) {
1252		fcport->stats_qfull = BFA_TRUE;
1253		bfa_reqq_winit(&fcport->stats_reqq_wait,
1254				bfa_fcport_send_stats_clear, fcport);
1255		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
1256				&fcport->stats_reqq_wait);
1257		return;
1258	}
1259	fcport->stats_qfull = BFA_FALSE;
1260
1261	bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
1262	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
1263			bfa_lpuid(fcport->bfa));
1264	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
1265}
1266
1267/**
1268 *  bfa_pport_public
1269 */
1270
1271/**
1272 * Called to initialize port attributes
1273 */
1274void
1275bfa_fcport_init(struct bfa_s *bfa)
1276{
1277	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1278
1279	/**
1280	 * Initialize port attributes from IOC hardware data.
1281	 */
1282	bfa_fcport_set_wwns(fcport);
1283	if (fcport->cfg.maxfrsize == 0)
1284		fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
1285	fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
1286	fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
1287
1288	bfa_assert(fcport->cfg.maxfrsize);
1289	bfa_assert(fcport->cfg.rx_bbcredit);
1290	bfa_assert(fcport->speed_sup);
1291}
1292
1293
1294/**
1295 * Firmware message handler.
1296 */
1297void
1298bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
1299{
1300	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1301	union bfi_fcport_i2h_msg_u i2hmsg;
1302
1303	i2hmsg.msg = msg;
1304	fcport->event_arg.i2hmsg = i2hmsg;
1305
1306	switch (msg->mhdr.msg_id) {
1307	case BFI_FCPORT_I2H_ENABLE_RSP:
1308		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
1309			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
1310		break;
1311
1312	case BFI_FCPORT_I2H_DISABLE_RSP:
1313		if (fcport->msgtag == i2hmsg.pdisable_rsp->msgtag)
1314			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
1315		break;
1316
1317	case BFI_FCPORT_I2H_EVENT:
1318		switch (i2hmsg.event->link_state.linkstate) {
1319		case BFA_PPORT_LINKUP:
1320			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
1321			break;
1322		case BFA_PPORT_LINKDOWN:
1323			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
1324			break;
1325		case BFA_PPORT_TRUNK_LINKDOWN:
1326			/** todo: event notification */
1327			break;
1328		}
1329		break;
1330
1331	case BFI_FCPORT_I2H_STATS_GET_RSP:
1332		/*
1333		 * check for timer pop before processing the rsp
1334		 */
1335		if (fcport->stats_busy == BFA_FALSE ||
1336			fcport->stats_status == BFA_STATUS_ETIMER)
1337			break;
1338
1339		bfa_timer_stop(&fcport->timer);
1340		fcport->stats_status = i2hmsg.pstatsget_rsp->status;
1341		bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1342				__bfa_cb_fcport_stats_get, fcport);
1343		break;
1344
1345	case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
1346		/*
1347		 * check for timer pop before processing the rsp
1348		 */
1349		if (fcport->stats_busy == BFA_FALSE ||
1350			fcport->stats_status == BFA_STATUS_ETIMER)
1351			break;
1352
1353		bfa_timer_stop(&fcport->timer);
1354		fcport->stats_status = BFA_STATUS_OK;
1355		bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
1356				__bfa_cb_fcport_stats_clr, fcport);
1357		break;
1358
1359	default:
1360		bfa_assert(0);
1361	break;
1362	}
1363}
1364
1365/**
1366 *  bfa_pport_api
1367 */
1368
1369/**
1370 * Registered callback for port events.
1371 */
1372void
1373bfa_fcport_event_register(struct bfa_s *bfa,
1374			 void (*cbfn) (void *cbarg, bfa_pport_event_t event),
1375			 void *cbarg)
1376{
1377	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1378
1379	fcport->event_cbfn = cbfn;
1380	fcport->event_cbarg = cbarg;
1381}
1382
1383bfa_status_t
1384bfa_fcport_enable(struct bfa_s *bfa)
1385{
1386	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1387	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1388	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1389
1390	/* if port is PBC disabled, return error */
1391	if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
1392		bfa_trc(bfa, fcport->pwwn);
1393		return BFA_STATUS_PBC;
1394	}
1395
1396	if (bfa_ioc_is_disabled(&bfa->ioc))
1397		return BFA_STATUS_IOC_DISABLED;
1398
1399	if (fcport->diag_busy)
1400		return BFA_STATUS_DIAG_BUSY;
1401	else if (bfa_sm_cmp_state
1402		 (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
1403		return BFA_STATUS_DEVBUSY;
1404
1405	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
1406	return BFA_STATUS_OK;
1407}
1408
1409bfa_status_t
1410bfa_fcport_disable(struct bfa_s *bfa)
1411{
1412	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1413	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1414	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1415
1416	/* if port is PBC disabled, return error */
1417	if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
1418		bfa_trc(bfa, fcport->pwwn);
1419		return BFA_STATUS_PBC;
1420	}
1421
1422	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
1423	return BFA_STATUS_OK;
1424}
1425
1426/**
1427 * Configure port speed.
1428 */
1429bfa_status_t
1430bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1431{
1432	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1433
1434	bfa_trc(bfa, speed);
1435
1436	if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
1437		bfa_trc(bfa, fcport->speed_sup);
1438		return BFA_STATUS_UNSUPP_SPEED;
1439	}
1440
1441	fcport->cfg.speed = speed;
1442
1443	return BFA_STATUS_OK;
1444}
1445
1446/**
1447 * Get current speed.
1448 */
1449enum bfa_pport_speed
1450bfa_fcport_get_speed(struct bfa_s *bfa)
1451{
1452	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1453
1454	return fcport->speed;
1455}
1456
1457/**
1458 * Configure port topology.
1459 */
1460bfa_status_t
1461bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1462{
1463	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1464
1465	bfa_trc(bfa, topology);
1466	bfa_trc(bfa, fcport->cfg.topology);
1467
1468	switch (topology) {
1469	case BFA_PPORT_TOPOLOGY_P2P:
1470	case BFA_PPORT_TOPOLOGY_LOOP:
1471	case BFA_PPORT_TOPOLOGY_AUTO:
1472		break;
1473
1474	default:
1475		return BFA_STATUS_EINVAL;
1476	}
1477
1478	fcport->cfg.topology = topology;
1479	return BFA_STATUS_OK;
1480}
1481
1482/**
1483 * Get current topology.
1484 */
1485enum bfa_pport_topology
1486bfa_fcport_get_topology(struct bfa_s *bfa)
1487{
1488	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1489
1490	return fcport->topology;
1491}
1492
1493bfa_status_t
1494bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
1495{
1496	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1497
1498	bfa_trc(bfa, alpa);
1499	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
1500	bfa_trc(bfa, fcport->cfg.hardalpa);
1501
1502	fcport->cfg.cfg_hardalpa = BFA_TRUE;
1503	fcport->cfg.hardalpa = alpa;
1504
1505	return BFA_STATUS_OK;
1506}
1507
1508bfa_status_t
1509bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
1510{
1511	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1512
1513	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
1514	bfa_trc(bfa, fcport->cfg.hardalpa);
1515
1516	fcport->cfg.cfg_hardalpa = BFA_FALSE;
1517	return BFA_STATUS_OK;
1518}
1519
1520bfa_boolean_t
1521bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
1522{
1523	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1524
1525	*alpa = fcport->cfg.hardalpa;
1526	return fcport->cfg.cfg_hardalpa;
1527}
1528
1529u8
1530bfa_fcport_get_myalpa(struct bfa_s *bfa)
1531{
1532	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1533
1534	return fcport->myalpa;
1535}
1536
1537bfa_status_t
1538bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1539{
1540	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1541
1542	bfa_trc(bfa, maxfrsize);
1543	bfa_trc(bfa, fcport->cfg.maxfrsize);
1544
1545	/*
1546	 * with in range
1547	 */
1548	if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
1549		return BFA_STATUS_INVLD_DFSZ;
1550
1551	/*
1552	 * power of 2, if not the max frame size of 2112
1553	 */
1554	if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
1555		return BFA_STATUS_INVLD_DFSZ;
1556
1557	fcport->cfg.maxfrsize = maxfrsize;
1558	return BFA_STATUS_OK;
1559}
1560
1561u16
1562bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
1563{
1564	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1565
1566	return fcport->cfg.maxfrsize;
1567}
1568
1569u32
1570bfa_fcport_mypid(struct bfa_s *bfa)
1571{
1572	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1573
1574	return fcport->mypid;
1575}
1576
1577u8
1578bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
1579{
1580	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1581
1582	return fcport->cfg.rx_bbcredit;
1583}
1584
1585void
1586bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1587{
1588	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1589
1590	fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
1591	bfa_fcport_send_txcredit(fcport);
1592}
1593
1594/**
1595 * Get port attributes.
1596 */
1597
1598wwn_t
1599bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
1600{
1601	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1602	if (node)
1603		return fcport->nwwn;
1604	else
1605		return fcport->pwwn;
1606}
1607
1608void
1609bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
1610{
1611	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1612	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1613	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1614
1615	bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
1616
1617	attr->nwwn = fcport->nwwn;
1618	attr->pwwn = fcport->pwwn;
1619
1620	attr->factorypwwn =  bfa_ioc_get_mfg_pwwn(&bfa->ioc);
1621	attr->factorynwwn =  bfa_ioc_get_mfg_nwwn(&bfa->ioc);
1622
1623	bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
1624		      sizeof(struct bfa_pport_cfg_s));
1625	/*
1626	 * speed attributes
1627	 */
1628	attr->pport_cfg.speed = fcport->cfg.speed;
1629	attr->speed_supported = fcport->speed_sup;
1630	attr->speed = fcport->speed;
1631	attr->cos_supported = FC_CLASS_3;
1632
1633	/*
1634	 * topology attributes
1635	 */
1636	attr->pport_cfg.topology = fcport->cfg.topology;
1637	attr->topology = fcport->topology;
1638
1639	/*
1640	 * beacon attributes
1641	 */
1642	attr->beacon = fcport->beacon;
1643	attr->link_e2e_beacon = fcport->link_e2e_beacon;
1644	attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
1645
1646	attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
1647	attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
1648
1649	/* PBC Disabled State */
1650	if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED)
1651		attr->port_state = BFA_PPORT_ST_PREBOOT_DISABLED;
1652	else {
1653		attr->port_state = bfa_sm_to_state(
1654				hal_pport_sm_table, fcport->sm);
1655		if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
1656			attr->port_state = BFA_PPORT_ST_IOCDIS;
1657		else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
1658			attr->port_state = BFA_PPORT_ST_FWMISMATCH;
1659	}
1660}
1661
1662#define BFA_FCPORT_STATS_TOV	1000
1663
1664/**
1665 * Fetch port attributes (FCQoS or FCoE).
1666 */
1667bfa_status_t
1668bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1669		    bfa_cb_pport_t cbfn, void *cbarg)
1670{
1671	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1672
1673	if (fcport->stats_busy) {
1674		bfa_trc(bfa, fcport->stats_busy);
1675		return BFA_STATUS_DEVBUSY;
1676	}
1677
1678	fcport->stats_busy  = BFA_TRUE;
1679	fcport->stats_ret   = stats;
1680	fcport->stats_cbfn  = cbfn;
1681	fcport->stats_cbarg = cbarg;
1682
1683	bfa_fcport_send_stats_get(fcport);
1684
1685	bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
1686		fcport, BFA_FCPORT_STATS_TOV);
1687	return BFA_STATUS_OK;
1688}
1689
1690/**
1691 * Reset port statistics (FCQoS or FCoE).
1692 */
1693bfa_status_t
1694bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1695{
1696	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1697
1698	if (fcport->stats_busy) {
1699		bfa_trc(bfa, fcport->stats_busy);
1700		return BFA_STATUS_DEVBUSY;
1701	}
1702
1703	fcport->stats_busy = BFA_TRUE;
1704	fcport->stats_cbfn = cbfn;
1705	fcport->stats_cbarg = cbarg;
1706
1707	bfa_fcport_send_stats_clear(fcport);
1708
1709	bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
1710			fcport, BFA_FCPORT_STATS_TOV);
1711	return BFA_STATUS_OK;
1712}
1713
1714/**
1715 * Fetch FCQoS port statistics
1716 */
1717bfa_status_t
1718bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1719	bfa_cb_pport_t cbfn, void *cbarg)
1720{
1721	/* Meaningful only for FC mode */
1722	bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
1723
1724	return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
1725}
1726
1727/**
1728 * Reset FCoE port statistics
1729 */
1730bfa_status_t
1731bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1732{
1733	/* Meaningful only for FC mode */
1734	bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
1735
1736	return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
1737}
1738
1739/**
1740 * Fetch FCQoS port statistics
1741 */
1742bfa_status_t
1743bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
1744	bfa_cb_pport_t cbfn, void *cbarg)
1745{
1746	/* Meaningful only for FCoE mode */
1747	bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
1748
1749	return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
1750}
1751
1752/**
1753 * Reset FCoE port statistics
1754 */
1755bfa_status_t
1756bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1757{
1758	/* Meaningful only for FCoE mode */
1759	bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
1760
1761	return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
1762}
1763
1764bfa_status_t
1765bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
1766{
1767	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1768
1769	bfa_trc(bfa, bitmap);
1770	bfa_trc(bfa, fcport->cfg.trunked);
1771	bfa_trc(bfa, fcport->cfg.trunk_ports);
1772
1773	if (!bitmap || (bitmap & (bitmap - 1)))
1774		return BFA_STATUS_EINVAL;
1775
1776	fcport->cfg.trunked = BFA_TRUE;
1777	fcport->cfg.trunk_ports = bitmap;
1778
1779	return BFA_STATUS_OK;
1780}
1781
1782void
1783bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
1784{
1785	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1786
1787	qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
1788	qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
1789}
1790
1791void
1792bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
1793			  struct bfa_qos_vc_attr_s *qos_vc_attr)
1794{
1795	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1796	struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
1797	u32        i = 0;
1798
1799	qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
1800	qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit);
1801	qos_vc_attr->elp_opmode_flags =
1802		bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
1803
1804	/*
1805	 * Individual VC info
1806	 */
1807	while (i < qos_vc_attr->total_vc_count) {
1808		qos_vc_attr->vc_info[i].vc_credit =
1809			bfa_vc_attr->vc_info[i].vc_credit;
1810		qos_vc_attr->vc_info[i].borrow_credit =
1811			bfa_vc_attr->vc_info[i].borrow_credit;
1812		qos_vc_attr->vc_info[i].priority =
1813			bfa_vc_attr->vc_info[i].priority;
1814		++i;
1815	}
1816}
1817
1818/**
1819 * Fetch port attributes.
1820 */
1821bfa_status_t
1822bfa_fcport_trunk_disable(struct bfa_s *bfa)
1823{
1824	return BFA_STATUS_OK;
1825}
1826
1827bfa_boolean_t
1828bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
1829{
1830	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1831
1832	*bitmap = fcport->cfg.trunk_ports;
1833	return fcport->cfg.trunked;
1834}
1835
1836bfa_boolean_t
1837bfa_fcport_is_disabled(struct bfa_s *bfa)
1838{
1839	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1840
1841	return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
1842		BFA_PPORT_ST_DISABLED;
1843
1844}
1845
1846bfa_boolean_t
1847bfa_fcport_is_ratelim(struct bfa_s *bfa)
1848{
1849	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1850
1851	return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
1852
1853}
1854
1855void
1856bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
1857{
1858	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1859	enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
1860
1861	bfa_trc(bfa, on_off);
1862	bfa_trc(bfa, fcport->cfg.qos_enabled);
1863
1864	bfa_trc(bfa, ioc_type);
1865
1866	if (ioc_type == BFA_IOC_TYPE_FC) {
1867		fcport->cfg.qos_enabled = on_off;
1868		/**
1869		 * Notify fcpim of the change in QoS state
1870		 */
1871		bfa_fcpim_update_ioredirect(bfa);
1872	}
1873}
1874
1875void
1876bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
1877{
1878	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1879
1880	bfa_trc(bfa, on_off);
1881	bfa_trc(bfa, fcport->cfg.ratelimit);
1882
1883	fcport->cfg.ratelimit = on_off;
1884	if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
1885		fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
1886}
1887
1888/**
1889 * Configure default minimum ratelim speed
1890 */
1891bfa_status_t
1892bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1893{
1894	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1895
1896	bfa_trc(bfa, speed);
1897
1898	/*
1899	 * Auto and speeds greater than the supported speed, are invalid
1900	 */
1901	if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
1902		bfa_trc(bfa, fcport->speed_sup);
1903		return BFA_STATUS_UNSUPP_SPEED;
1904	}
1905
1906	fcport->cfg.trl_def_speed = speed;
1907
1908	return BFA_STATUS_OK;
1909}
1910
1911/**
1912 * Get default minimum ratelim speed
1913 */
1914enum bfa_pport_speed
1915bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
1916{
1917	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1918
1919	bfa_trc(bfa, fcport->cfg.trl_def_speed);
1920	return fcport->cfg.trl_def_speed;
1921
1922}
1923
1924void
1925bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
1926{
1927	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1928
1929	bfa_trc(bfa, status);
1930	bfa_trc(bfa, fcport->diag_busy);
1931
1932	fcport->diag_busy = status;
1933}
1934
1935void
1936bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
1937		 bfa_boolean_t link_e2e_beacon)
1938{
1939	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1940
1941	bfa_trc(bfa, beacon);
1942	bfa_trc(bfa, link_e2e_beacon);
1943	bfa_trc(bfa, fcport->beacon);
1944	bfa_trc(bfa, fcport->link_e2e_beacon);
1945
1946	fcport->beacon = beacon;
1947	fcport->link_e2e_beacon = link_e2e_beacon;
1948}
1949
1950bfa_boolean_t
1951bfa_fcport_is_linkup(struct bfa_s *bfa)
1952{
1953	return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
1954}
1955
1956bfa_boolean_t
1957bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
1958{
1959	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
1960
1961	return fcport->cfg.qos_enabled;
1962}
1963