Merge branch 'for-2.6.33' of git://linux-nfs.org/~bfields/linux
[deliverable/linux.git] / drivers / scsi / bfa / bfa_fcport.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 #include <bfa.h>
19 #include <bfa_svc.h>
20 #include <bfi/bfi_pport.h>
21 #include <cs/bfa_debug.h>
22 #include <aen/bfa_aen.h>
23 #include <cs/bfa_plog.h>
24 #include <aen/bfa_aen_port.h>
25
26 BFA_TRC_FILE(HAL, PPORT);
27 BFA_MODULE(pport);
28
29 #define bfa_pport_callback(__pport, __event) do { \
30 if ((__pport)->bfa->fcs) { \
31 (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
32 } else { \
33 (__pport)->hcb_event = (__event); \
34 bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
35 __bfa_cb_port_event, (__pport)); \
36 } \
37 } while (0)
38
39 /*
40 * The port is considered disabled if corresponding physical port or IOC are
41 * disabled explicitly
42 */
43 #define BFA_PORT_IS_DISABLED(bfa) \
44 ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
45 (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
46
47 /*
48 * forward declarations
49 */
50 static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
51 static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
52 static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
53 static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
54 static void bfa_pport_set_wwns(struct bfa_pport_s *port);
55 static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
56 static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
57 static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
58 static void bfa_port_stats_timeout(void *cbarg);
59 static void bfa_port_stats_clr_timeout(void *cbarg);
60
61 /**
62 * bfa_pport_private
63 */
64
65 /**
66 * BFA port state machine events
67 */
68 enum bfa_pport_sm_event {
69 BFA_PPORT_SM_START = 1, /* start port state machine */
70 BFA_PPORT_SM_STOP = 2, /* stop port state machine */
71 BFA_PPORT_SM_ENABLE = 3, /* enable port */
72 BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */
73 BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
74 BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */
75 BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */
76 BFA_PPORT_SM_QRESUME = 8, /* CQ space available */
77 BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */
78 };
79
80 static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
81 enum bfa_pport_sm_event event);
82 static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
83 enum bfa_pport_sm_event event);
84 static void bfa_pport_sm_enabling(struct bfa_pport_s *pport,
85 enum bfa_pport_sm_event event);
86 static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
87 enum bfa_pport_sm_event event);
88 static void bfa_pport_sm_linkup(struct bfa_pport_s *pport,
89 enum bfa_pport_sm_event event);
90 static void bfa_pport_sm_disabling(struct bfa_pport_s *pport,
91 enum bfa_pport_sm_event event);
92 static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
93 enum bfa_pport_sm_event event);
94 static void bfa_pport_sm_disabled(struct bfa_pport_s *pport,
95 enum bfa_pport_sm_event event);
96 static void bfa_pport_sm_stopped(struct bfa_pport_s *pport,
97 enum bfa_pport_sm_event event);
98 static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
99 enum bfa_pport_sm_event event);
100 static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
101 enum bfa_pport_sm_event event);
102
103 static struct bfa_sm_table_s hal_pport_sm_table[] = {
104 {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
105 {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
106 {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
107 {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
108 {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
109 {BFA_SM(bfa_pport_sm_disabling_qwait),
110 BFA_PPORT_ST_DISABLING_QWAIT},
111 {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
112 {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
113 {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
114 {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
115 {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
116 };
117
118 static void
119 bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
120 {
121 union bfa_aen_data_u aen_data;
122 struct bfa_log_mod_s *logmod = pport->bfa->logm;
123 wwn_t pwwn = pport->pwwn;
124 char pwwn_ptr[BFA_STRING_32];
125 struct bfa_ioc_attr_s ioc_attr;
126
127 wwn2str(pwwn_ptr, pwwn);
128 switch (event) {
129 case BFA_PORT_AEN_ONLINE:
130 bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
131 break;
132 case BFA_PORT_AEN_OFFLINE:
133 bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
134 break;
135 case BFA_PORT_AEN_ENABLE:
136 bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
137 break;
138 case BFA_PORT_AEN_DISABLE:
139 bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
140 break;
141 case BFA_PORT_AEN_DISCONNECT:
142 bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
143 break;
144 case BFA_PORT_AEN_QOS_NEG:
145 bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
146 break;
147 default:
148 break;
149 }
150
151 bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
152 aen_data.port.ioc_type = ioc_attr.ioc_type;
153 aen_data.port.pwwn = pwwn;
154 }
155
156 static void
157 bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
158 {
159 bfa_trc(pport->bfa, event);
160
161 switch (event) {
162 case BFA_PPORT_SM_START:
163 /**
164 * Start event after IOC is configured and BFA is started.
165 */
166 if (bfa_pport_send_enable(pport))
167 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
168 else
169 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
170 break;
171
172 case BFA_PPORT_SM_ENABLE:
173 /**
174 * Port is persistently configured to be in enabled state. Do
175 * not change state. Port enabling is done when START event is
176 * received.
177 */
178 break;
179
180 case BFA_PPORT_SM_DISABLE:
181 /**
182 * If a port is persistently configured to be disabled, the
183 * first event will a port disable request.
184 */
185 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
186 break;
187
188 case BFA_PPORT_SM_HWFAIL:
189 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
190 break;
191
192 default:
193 bfa_sm_fault(pport->bfa, event);
194 }
195 }
196
197 static void
198 bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
199 enum bfa_pport_sm_event event)
200 {
201 bfa_trc(pport->bfa, event);
202
203 switch (event) {
204 case BFA_PPORT_SM_QRESUME:
205 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
206 bfa_pport_send_enable(pport);
207 break;
208
209 case BFA_PPORT_SM_STOP:
210 bfa_reqq_wcancel(&pport->reqq_wait);
211 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
212 break;
213
214 case BFA_PPORT_SM_ENABLE:
215 /**
216 * Already enable is in progress.
217 */
218 break;
219
220 case BFA_PPORT_SM_DISABLE:
221 /**
222 * Just send disable request to firmware when room becomes
223 * available in request queue.
224 */
225 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
226 bfa_reqq_wcancel(&pport->reqq_wait);
227 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
228 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
229 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
230 break;
231
232 case BFA_PPORT_SM_LINKUP:
233 case BFA_PPORT_SM_LINKDOWN:
234 /**
235 * Possible to get link events when doing back-to-back
236 * enable/disables.
237 */
238 break;
239
240 case BFA_PPORT_SM_HWFAIL:
241 bfa_reqq_wcancel(&pport->reqq_wait);
242 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
243 break;
244
245 default:
246 bfa_sm_fault(pport->bfa, event);
247 }
248 }
249
250 static void
251 bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
252 {
253 bfa_trc(pport->bfa, event);
254
255 switch (event) {
256 case BFA_PPORT_SM_FWRSP:
257 case BFA_PPORT_SM_LINKDOWN:
258 bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
259 break;
260
261 case BFA_PPORT_SM_LINKUP:
262 bfa_pport_update_linkinfo(pport);
263 bfa_sm_set_state(pport, bfa_pport_sm_linkup);
264
265 bfa_assert(pport->event_cbfn);
266 bfa_pport_callback(pport, BFA_PPORT_LINKUP);
267 break;
268
269 case BFA_PPORT_SM_ENABLE:
270 /**
271 * Already being enabled.
272 */
273 break;
274
275 case BFA_PPORT_SM_DISABLE:
276 if (bfa_pport_send_disable(pport))
277 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
278 else
279 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
280
281 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
282 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
283 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
284 break;
285
286 case BFA_PPORT_SM_STOP:
287 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
288 break;
289
290 case BFA_PPORT_SM_HWFAIL:
291 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
292 break;
293
294 default:
295 bfa_sm_fault(pport->bfa, event);
296 }
297 }
298
299 static void
300 bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
301 {
302 bfa_trc(pport->bfa, event);
303
304 switch (event) {
305 case BFA_PPORT_SM_LINKUP:
306 bfa_pport_update_linkinfo(pport);
307 bfa_sm_set_state(pport, bfa_pport_sm_linkup);
308 bfa_assert(pport->event_cbfn);
309 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
310 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
311 bfa_pport_callback(pport, BFA_PPORT_LINKUP);
312 bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
313 /**
314 * If QoS is enabled and it is not online,
315 * Send a separate event.
316 */
317 if ((pport->cfg.qos_enabled)
318 && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
319 bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
320
321 break;
322
323 case BFA_PPORT_SM_LINKDOWN:
324 /**
325 * Possible to get link down event.
326 */
327 break;
328
329 case BFA_PPORT_SM_ENABLE:
330 /**
331 * Already enabled.
332 */
333 break;
334
335 case BFA_PPORT_SM_DISABLE:
336 if (bfa_pport_send_disable(pport))
337 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
338 else
339 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
340
341 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
342 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
343 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
344 break;
345
346 case BFA_PPORT_SM_STOP:
347 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
348 break;
349
350 case BFA_PPORT_SM_HWFAIL:
351 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
352 break;
353
354 default:
355 bfa_sm_fault(pport->bfa, event);
356 }
357 }
358
359 static void
360 bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
361 {
362 bfa_trc(pport->bfa, event);
363
364 switch (event) {
365 case BFA_PPORT_SM_ENABLE:
366 /**
367 * Already enabled.
368 */
369 break;
370
371 case BFA_PPORT_SM_DISABLE:
372 if (bfa_pport_send_disable(pport))
373 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
374 else
375 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
376
377 bfa_pport_reset_linkinfo(pport);
378 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
379 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
380 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
381 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
382 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
383 break;
384
385 case BFA_PPORT_SM_LINKDOWN:
386 bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
387 bfa_pport_reset_linkinfo(pport);
388 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
389 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
390 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
391 if (BFA_PORT_IS_DISABLED(pport->bfa))
392 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
393 else
394 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
395 break;
396
397 case BFA_PPORT_SM_STOP:
398 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
399 bfa_pport_reset_linkinfo(pport);
400 if (BFA_PORT_IS_DISABLED(pport->bfa))
401 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
402 else
403 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
404 break;
405
406 case BFA_PPORT_SM_HWFAIL:
407 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
408 bfa_pport_reset_linkinfo(pport);
409 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
410 if (BFA_PORT_IS_DISABLED(pport->bfa))
411 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
412 else
413 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
414 break;
415
416 default:
417 bfa_sm_fault(pport->bfa, event);
418 }
419 }
420
421 static void
422 bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
423 enum bfa_pport_sm_event event)
424 {
425 bfa_trc(pport->bfa, event);
426
427 switch (event) {
428 case BFA_PPORT_SM_QRESUME:
429 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
430 bfa_pport_send_disable(pport);
431 break;
432
433 case BFA_PPORT_SM_STOP:
434 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
435 bfa_reqq_wcancel(&pport->reqq_wait);
436 break;
437
438 case BFA_PPORT_SM_DISABLE:
439 /**
440 * Already being disabled.
441 */
442 break;
443
444 case BFA_PPORT_SM_LINKUP:
445 case BFA_PPORT_SM_LINKDOWN:
446 /**
447 * Possible to get link events when doing back-to-back
448 * enable/disables.
449 */
450 break;
451
452 case BFA_PPORT_SM_HWFAIL:
453 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
454 bfa_reqq_wcancel(&pport->reqq_wait);
455 break;
456
457 default:
458 bfa_sm_fault(pport->bfa, event);
459 }
460 }
461
462 static void
463 bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
464 {
465 bfa_trc(pport->bfa, event);
466
467 switch (event) {
468 case BFA_PPORT_SM_FWRSP:
469 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
470 break;
471
472 case BFA_PPORT_SM_DISABLE:
473 /**
474 * Already being disabled.
475 */
476 break;
477
478 case BFA_PPORT_SM_ENABLE:
479 if (bfa_pport_send_enable(pport))
480 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
481 else
482 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
483
484 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
485 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
486 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
487 break;
488
489 case BFA_PPORT_SM_STOP:
490 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
491 break;
492
493 case BFA_PPORT_SM_LINKUP:
494 case BFA_PPORT_SM_LINKDOWN:
495 /**
496 * Possible to get link events when doing back-to-back
497 * enable/disables.
498 */
499 break;
500
501 case BFA_PPORT_SM_HWFAIL:
502 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
503 break;
504
505 default:
506 bfa_sm_fault(pport->bfa, event);
507 }
508 }
509
510 static void
511 bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
512 {
513 bfa_trc(pport->bfa, event);
514
515 switch (event) {
516 case BFA_PPORT_SM_START:
517 /**
518 * Ignore start event for a port that is disabled.
519 */
520 break;
521
522 case BFA_PPORT_SM_STOP:
523 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
524 break;
525
526 case BFA_PPORT_SM_ENABLE:
527 if (bfa_pport_send_enable(pport))
528 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
529 else
530 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
531
532 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
533 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
534 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
535 break;
536
537 case BFA_PPORT_SM_DISABLE:
538 /**
539 * Already disabled.
540 */
541 break;
542
543 case BFA_PPORT_SM_HWFAIL:
544 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
545 break;
546
547 default:
548 bfa_sm_fault(pport->bfa, event);
549 }
550 }
551
552 static void
553 bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
554 {
555 bfa_trc(pport->bfa, event);
556
557 switch (event) {
558 case BFA_PPORT_SM_START:
559 if (bfa_pport_send_enable(pport))
560 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
561 else
562 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
563 break;
564
565 default:
566 /**
567 * Ignore all other events.
568 */
569 ;
570 }
571 }
572
573 /**
574 * Port is enabled. IOC is down/failed.
575 */
576 static void
577 bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
578 {
579 bfa_trc(pport->bfa, event);
580
581 switch (event) {
582 case BFA_PPORT_SM_START:
583 if (bfa_pport_send_enable(pport))
584 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
585 else
586 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
587 break;
588
589 default:
590 /**
591 * Ignore all events.
592 */
593 ;
594 }
595 }
596
597 /**
598 * Port is disabled. IOC is down/failed.
599 */
600 static void
601 bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
602 {
603 bfa_trc(pport->bfa, event);
604
605 switch (event) {
606 case BFA_PPORT_SM_START:
607 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
608 break;
609
610 case BFA_PPORT_SM_ENABLE:
611 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
612 break;
613
614 default:
615 /**
616 * Ignore all events.
617 */
618 ;
619 }
620 }
621
622
623
624 /**
625 * bfa_pport_private
626 */
627
628 static void
629 __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
630 {
631 struct bfa_pport_s *pport = cbarg;
632
633 if (complete)
634 pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
635 }
636
637 #define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
638 BFA_CACHELINE_SZ))
639
640 static void
641 bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
642 u32 *dm_len)
643 {
644 *dm_len += PPORT_STATS_DMA_SZ;
645 }
646
647 static void
648 bfa_pport_qresume(void *cbarg)
649 {
650 struct bfa_pport_s *port = cbarg;
651
652 bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
653 }
654
655 static void
656 bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
657 {
658 u8 *dm_kva;
659 u64 dm_pa;
660
661 dm_kva = bfa_meminfo_dma_virt(meminfo);
662 dm_pa = bfa_meminfo_dma_phys(meminfo);
663
664 pport->stats_kva = dm_kva;
665 pport->stats_pa = dm_pa;
666 pport->stats = (union bfa_pport_stats_u *)dm_kva;
667
668 dm_kva += PPORT_STATS_DMA_SZ;
669 dm_pa += PPORT_STATS_DMA_SZ;
670
671 bfa_meminfo_dma_virt(meminfo) = dm_kva;
672 bfa_meminfo_dma_phys(meminfo) = dm_pa;
673 }
674
675 /**
676 * Memory initialization.
677 */
678 static void
679 bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
680 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
681 {
682 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
683 struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
684
685 bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
686 pport->bfa = bfa;
687
688 bfa_pport_mem_claim(pport, meminfo);
689
690 bfa_sm_set_state(pport, bfa_pport_sm_uninit);
691
692 /**
693 * initialize and set default configuration
694 */
695 port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
696 port_cfg->speed = BFA_PPORT_SPEED_AUTO;
697 port_cfg->trunked = BFA_FALSE;
698 port_cfg->maxfrsize = 0;
699
700 port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
701
702 bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
703 }
704
705 static void
706 bfa_pport_initdone(struct bfa_s *bfa)
707 {
708 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
709
710 /**
711 * Initialize port attributes from IOC hardware data.
712 */
713 bfa_pport_set_wwns(pport);
714 if (pport->cfg.maxfrsize == 0)
715 pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
716 pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
717 pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
718
719 bfa_assert(pport->cfg.maxfrsize);
720 bfa_assert(pport->cfg.rx_bbcredit);
721 bfa_assert(pport->speed_sup);
722 }
723
724 static void
725 bfa_pport_detach(struct bfa_s *bfa)
726 {
727 }
728
729 /**
730 * Called when IOC is ready.
731 */
732 static void
733 bfa_pport_start(struct bfa_s *bfa)
734 {
735 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
736 }
737
738 /**
739 * Called before IOC is stopped.
740 */
741 static void
742 bfa_pport_stop(struct bfa_s *bfa)
743 {
744 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
745 }
746
747 /**
748 * Called when IOC failure is detected.
749 */
750 static void
751 bfa_pport_iocdisable(struct bfa_s *bfa)
752 {
753 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
754 }
755
756 static void
757 bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
758 {
759 struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
760
761 pport->speed = pevent->link_state.speed;
762 pport->topology = pevent->link_state.topology;
763
764 if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
765 pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
766
767 /*
768 * QoS Details
769 */
770 bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
771 bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
772
773 bfa_trc(pport->bfa, pport->speed);
774 bfa_trc(pport->bfa, pport->topology);
775 }
776
777 static void
778 bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
779 {
780 pport->speed = BFA_PPORT_SPEED_UNKNOWN;
781 pport->topology = BFA_PPORT_TOPOLOGY_NONE;
782 }
783
784 /**
785 * Send port enable message to firmware.
786 */
787 static bfa_boolean_t
788 bfa_pport_send_enable(struct bfa_pport_s *port)
789 {
790 struct bfi_pport_enable_req_s *m;
791
792 /**
793 * Increment message tag before queue check, so that responses to old
794 * requests are discarded.
795 */
796 port->msgtag++;
797
798 /**
799 * check for room in queue to send request now
800 */
801 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
802 if (!m) {
803 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
804 return BFA_FALSE;
805 }
806
807 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
808 bfa_lpuid(port->bfa));
809 m->nwwn = port->nwwn;
810 m->pwwn = port->pwwn;
811 m->port_cfg = port->cfg;
812 m->msgtag = port->msgtag;
813 m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
814 bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
815 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
816 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
817
818 /**
819 * queue I/O message to firmware
820 */
821 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
822 return BFA_TRUE;
823 }
824
825 /**
826 * Send port disable message to firmware.
827 */
828 static bfa_boolean_t
829 bfa_pport_send_disable(struct bfa_pport_s *port)
830 {
831 bfi_pport_disable_req_t *m;
832
833 /**
834 * Increment message tag before queue check, so that responses to old
835 * requests are discarded.
836 */
837 port->msgtag++;
838
839 /**
840 * check for room in queue to send request now
841 */
842 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
843 if (!m) {
844 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
845 return BFA_FALSE;
846 }
847
848 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
849 bfa_lpuid(port->bfa));
850 m->msgtag = port->msgtag;
851
852 /**
853 * queue I/O message to firmware
854 */
855 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
856
857 return BFA_TRUE;
858 }
859
860 static void
861 bfa_pport_set_wwns(struct bfa_pport_s *port)
862 {
863 port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
864 port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
865
866 bfa_trc(port->bfa, port->pwwn);
867 bfa_trc(port->bfa, port->nwwn);
868 }
869
870 static void
871 bfa_port_send_txcredit(void *port_cbarg)
872 {
873
874 struct bfa_pport_s *port = port_cbarg;
875 struct bfi_pport_set_svc_params_req_s *m;
876
877 /**
878 * check for room in queue to send request now
879 */
880 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
881 if (!m) {
882 bfa_trc(port->bfa, port->cfg.tx_bbcredit);
883 return;
884 }
885
886 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
887 bfa_lpuid(port->bfa));
888 m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
889
890 /**
891 * queue I/O message to firmware
892 */
893 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
894 }
895
896
897
898 /**
899 * bfa_pport_public
900 */
901
902 /**
903 * Firmware message handler.
904 */
905 void
906 bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
907 {
908 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
909 union bfi_pport_i2h_msg_u i2hmsg;
910
911 i2hmsg.msg = msg;
912 pport->event_arg.i2hmsg = i2hmsg;
913
914 switch (msg->mhdr.msg_id) {
915 case BFI_PPORT_I2H_ENABLE_RSP:
916 if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
917 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
918 break;
919
920 case BFI_PPORT_I2H_DISABLE_RSP:
921 if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
922 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
923 break;
924
925 case BFI_PPORT_I2H_EVENT:
926 switch (i2hmsg.event->link_state.linkstate) {
927 case BFA_PPORT_LINKUP:
928 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
929 break;
930 case BFA_PPORT_LINKDOWN:
931 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
932 break;
933 case BFA_PPORT_TRUNK_LINKDOWN:
934 /** todo: event notification */
935 break;
936 }
937 break;
938
939 case BFI_PPORT_I2H_GET_STATS_RSP:
940 case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
941 /*
942 * check for timer pop before processing the rsp
943 */
944 if (pport->stats_busy == BFA_FALSE
945 || pport->stats_status == BFA_STATUS_ETIMER)
946 break;
947
948 bfa_timer_stop(&pport->timer);
949 pport->stats_status = i2hmsg.getstats_rsp->status;
950 bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
951 pport);
952 break;
953 case BFI_PPORT_I2H_CLEAR_STATS_RSP:
954 case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
955 /*
956 * check for timer pop before processing the rsp
957 */
958 if (pport->stats_busy == BFA_FALSE
959 || pport->stats_status == BFA_STATUS_ETIMER)
960 break;
961
962 bfa_timer_stop(&pport->timer);
963 pport->stats_status = BFA_STATUS_OK;
964 bfa_cb_queue(pport->bfa, &pport->hcb_qe,
965 __bfa_cb_port_stats_clr, pport);
966 break;
967
968 default:
969 bfa_assert(0);
970 }
971 }
972
973
974
975 /**
976 * bfa_pport_api
977 */
978
979 /**
980 * Registered callback for port events.
981 */
982 void
983 bfa_pport_event_register(struct bfa_s *bfa,
984 void (*cbfn) (void *cbarg, bfa_pport_event_t event),
985 void *cbarg)
986 {
987 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
988
989 pport->event_cbfn = cbfn;
990 pport->event_cbarg = cbarg;
991 }
992
993 bfa_status_t
994 bfa_pport_enable(struct bfa_s *bfa)
995 {
996 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
997
998 if (pport->diag_busy)
999 return BFA_STATUS_DIAG_BUSY;
1000 else if (bfa_sm_cmp_state
1001 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
1002 return BFA_STATUS_DEVBUSY;
1003
1004 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
1005 return BFA_STATUS_OK;
1006 }
1007
1008 bfa_status_t
1009 bfa_pport_disable(struct bfa_s *bfa)
1010 {
1011 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
1012 return BFA_STATUS_OK;
1013 }
1014
1015 /**
1016 * Configure port speed.
1017 */
1018 bfa_status_t
1019 bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1020 {
1021 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1022
1023 bfa_trc(bfa, speed);
1024
1025 if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
1026 bfa_trc(bfa, pport->speed_sup);
1027 return BFA_STATUS_UNSUPP_SPEED;
1028 }
1029
1030 pport->cfg.speed = speed;
1031
1032 return BFA_STATUS_OK;
1033 }
1034
1035 /**
1036 * Get current speed.
1037 */
1038 enum bfa_pport_speed
1039 bfa_pport_get_speed(struct bfa_s *bfa)
1040 {
1041 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1042
1043 return port->speed;
1044 }
1045
1046 /**
1047 * Configure port topology.
1048 */
1049 bfa_status_t
1050 bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1051 {
1052 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1053
1054 bfa_trc(bfa, topology);
1055 bfa_trc(bfa, pport->cfg.topology);
1056
1057 switch (topology) {
1058 case BFA_PPORT_TOPOLOGY_P2P:
1059 case BFA_PPORT_TOPOLOGY_LOOP:
1060 case BFA_PPORT_TOPOLOGY_AUTO:
1061 break;
1062
1063 default:
1064 return BFA_STATUS_EINVAL;
1065 }
1066
1067 pport->cfg.topology = topology;
1068 return BFA_STATUS_OK;
1069 }
1070
1071 /**
1072 * Get current topology.
1073 */
1074 enum bfa_pport_topology
1075 bfa_pport_get_topology(struct bfa_s *bfa)
1076 {
1077 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1078
1079 return port->topology;
1080 }
1081
1082 bfa_status_t
1083 bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
1084 {
1085 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1086
1087 bfa_trc(bfa, alpa);
1088 bfa_trc(bfa, pport->cfg.cfg_hardalpa);
1089 bfa_trc(bfa, pport->cfg.hardalpa);
1090
1091 pport->cfg.cfg_hardalpa = BFA_TRUE;
1092 pport->cfg.hardalpa = alpa;
1093
1094 return BFA_STATUS_OK;
1095 }
1096
1097 bfa_status_t
1098 bfa_pport_clr_hardalpa(struct bfa_s *bfa)
1099 {
1100 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1101
1102 bfa_trc(bfa, pport->cfg.cfg_hardalpa);
1103 bfa_trc(bfa, pport->cfg.hardalpa);
1104
1105 pport->cfg.cfg_hardalpa = BFA_FALSE;
1106 return BFA_STATUS_OK;
1107 }
1108
1109 bfa_boolean_t
1110 bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
1111 {
1112 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1113
1114 *alpa = port->cfg.hardalpa;
1115 return port->cfg.cfg_hardalpa;
1116 }
1117
1118 u8
1119 bfa_pport_get_myalpa(struct bfa_s *bfa)
1120 {
1121 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1122
1123 return port->myalpa;
1124 }
1125
1126 bfa_status_t
1127 bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1128 {
1129 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1130
1131 bfa_trc(bfa, maxfrsize);
1132 bfa_trc(bfa, pport->cfg.maxfrsize);
1133
1134 /*
1135 * with in range
1136 */
1137 if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
1138 return BFA_STATUS_INVLD_DFSZ;
1139
1140 /*
1141 * power of 2, if not the max frame size of 2112
1142 */
1143 if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
1144 return BFA_STATUS_INVLD_DFSZ;
1145
1146 pport->cfg.maxfrsize = maxfrsize;
1147 return BFA_STATUS_OK;
1148 }
1149
1150 u16
1151 bfa_pport_get_maxfrsize(struct bfa_s *bfa)
1152 {
1153 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1154
1155 return port->cfg.maxfrsize;
1156 }
1157
1158 u32
1159 bfa_pport_mypid(struct bfa_s *bfa)
1160 {
1161 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1162
1163 return port->mypid;
1164 }
1165
1166 u8
1167 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
1168 {
1169 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1170
1171 return port->cfg.rx_bbcredit;
1172 }
1173
1174 void
1175 bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1176 {
1177 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1178
1179 port->cfg.tx_bbcredit = (u8) tx_bbcredit;
1180 bfa_port_send_txcredit(port);
1181 }
1182
1183 /**
1184 * Get port attributes.
1185 */
1186
1187 wwn_t
1188 bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
1189 {
1190 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1191 if (node)
1192 return pport->nwwn;
1193 else
1194 return pport->pwwn;
1195 }
1196
1197 void
1198 bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
1199 {
1200 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1201
1202 bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
1203
1204 attr->nwwn = pport->nwwn;
1205 attr->pwwn = pport->pwwn;
1206
1207 bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
1208 sizeof(struct bfa_pport_cfg_s));
1209 /*
1210 * speed attributes
1211 */
1212 attr->pport_cfg.speed = pport->cfg.speed;
1213 attr->speed_supported = pport->speed_sup;
1214 attr->speed = pport->speed;
1215 attr->cos_supported = FC_CLASS_3;
1216
1217 /*
1218 * topology attributes
1219 */
1220 attr->pport_cfg.topology = pport->cfg.topology;
1221 attr->topology = pport->topology;
1222
1223 /*
1224 * beacon attributes
1225 */
1226 attr->beacon = pport->beacon;
1227 attr->link_e2e_beacon = pport->link_e2e_beacon;
1228 attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
1229
1230 attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
1231 attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
1232 attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
1233 if (bfa_ioc_is_disabled(&pport->bfa->ioc))
1234 attr->port_state = BFA_PPORT_ST_IOCDIS;
1235 else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
1236 attr->port_state = BFA_PPORT_ST_FWMISMATCH;
1237 }
1238
1239 static void
1240 bfa_port_stats_query(void *cbarg)
1241 {
1242 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1243 bfi_pport_get_stats_req_t *msg;
1244
1245 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1246
1247 if (!msg) {
1248 port->stats_qfull = BFA_TRUE;
1249 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
1250 port);
1251 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1252 return;
1253 }
1254 port->stats_qfull = BFA_FALSE;
1255
1256 bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
1257 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
1258 bfa_lpuid(port->bfa));
1259 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1260
1261 return;
1262 }
1263
1264 static void
1265 bfa_port_stats_clear(void *cbarg)
1266 {
1267 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1268 bfi_pport_clear_stats_req_t *msg;
1269
1270 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1271
1272 if (!msg) {
1273 port->stats_qfull = BFA_TRUE;
1274 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
1275 port);
1276 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1277 return;
1278 }
1279 port->stats_qfull = BFA_FALSE;
1280
1281 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
1282 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
1283 bfa_lpuid(port->bfa));
1284 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1285 return;
1286 }
1287
1288 static void
1289 bfa_port_qos_stats_clear(void *cbarg)
1290 {
1291 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1292 bfi_pport_clear_qos_stats_req_t *msg;
1293
1294 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1295
1296 if (!msg) {
1297 port->stats_qfull = BFA_TRUE;
1298 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
1299 port);
1300 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1301 return;
1302 }
1303 port->stats_qfull = BFA_FALSE;
1304
1305 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
1306 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
1307 bfa_lpuid(port->bfa));
1308 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1309 return;
1310 }
1311
1312 static void
1313 bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
1314 {
1315 u32 *dip = (u32 *) d;
1316 u32 *sip = (u32 *) s;
1317 int i;
1318
1319 /*
1320 * Do 64 bit fields swap first
1321 */
1322 for (i = 0;
1323 i <
1324 ((sizeof(union bfa_pport_stats_u) -
1325 sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
1326 #ifdef __BIGENDIAN
1327 dip[i] = bfa_os_ntohl(sip[i]);
1328 dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1329 #else
1330 dip[i] = bfa_os_ntohl(sip[i + 1]);
1331 dip[i + 1] = bfa_os_ntohl(sip[i]);
1332 #endif
1333 }
1334
1335 /*
1336 * Now swap the 32 bit fields
1337 */
1338 for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
1339 dip[i] = bfa_os_ntohl(sip[i]);
1340 }
1341
1342 static void
1343 __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
1344 {
1345 struct bfa_pport_s *port = cbarg;
1346
1347 if (complete) {
1348 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1349 } else {
1350 port->stats_busy = BFA_FALSE;
1351 port->stats_status = BFA_STATUS_OK;
1352 }
1353 }
1354
1355 static void
1356 bfa_port_stats_clr_timeout(void *cbarg)
1357 {
1358 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1359
1360 bfa_trc(port->bfa, port->stats_qfull);
1361
1362 if (port->stats_qfull) {
1363 bfa_reqq_wcancel(&port->stats_reqq_wait);
1364 port->stats_qfull = BFA_FALSE;
1365 }
1366
1367 port->stats_status = BFA_STATUS_ETIMER;
1368 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
1369 }
1370
1371 static void
1372 __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
1373 {
1374 struct bfa_pport_s *port = cbarg;
1375
1376 if (complete) {
1377 if (port->stats_status == BFA_STATUS_OK)
1378 bfa_pport_stats_swap(port->stats_ret, port->stats);
1379 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1380 } else {
1381 port->stats_busy = BFA_FALSE;
1382 port->stats_status = BFA_STATUS_OK;
1383 }
1384 }
1385
1386 static void
1387 bfa_port_stats_timeout(void *cbarg)
1388 {
1389 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1390
1391 bfa_trc(port->bfa, port->stats_qfull);
1392
1393 if (port->stats_qfull) {
1394 bfa_reqq_wcancel(&port->stats_reqq_wait);
1395 port->stats_qfull = BFA_FALSE;
1396 }
1397
1398 port->stats_status = BFA_STATUS_ETIMER;
1399 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
1400 }
1401
1402 #define BFA_PORT_STATS_TOV 1000
1403
1404 /**
1405 * Fetch port attributes.
1406 */
1407 bfa_status_t
1408 bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1409 bfa_cb_pport_t cbfn, void *cbarg)
1410 {
1411 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1412
1413 if (port->stats_busy) {
1414 bfa_trc(bfa, port->stats_busy);
1415 return BFA_STATUS_DEVBUSY;
1416 }
1417
1418 port->stats_busy = BFA_TRUE;
1419 port->stats_ret = stats;
1420 port->stats_cbfn = cbfn;
1421 port->stats_cbarg = cbarg;
1422
1423 bfa_port_stats_query(port);
1424
1425 bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
1426 BFA_PORT_STATS_TOV);
1427 return BFA_STATUS_OK;
1428 }
1429
1430 bfa_status_t
1431 bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1432 {
1433 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1434
1435 if (port->stats_busy) {
1436 bfa_trc(bfa, port->stats_busy);
1437 return BFA_STATUS_DEVBUSY;
1438 }
1439
1440 port->stats_busy = BFA_TRUE;
1441 port->stats_cbfn = cbfn;
1442 port->stats_cbarg = cbarg;
1443
1444 bfa_port_stats_clear(port);
1445
1446 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1447 BFA_PORT_STATS_TOV);
1448 return BFA_STATUS_OK;
1449 }
1450
1451 bfa_status_t
1452 bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
1453 {
1454 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1455
1456 bfa_trc(bfa, bitmap);
1457 bfa_trc(bfa, pport->cfg.trunked);
1458 bfa_trc(bfa, pport->cfg.trunk_ports);
1459
1460 if (!bitmap || (bitmap & (bitmap - 1)))
1461 return BFA_STATUS_EINVAL;
1462
1463 pport->cfg.trunked = BFA_TRUE;
1464 pport->cfg.trunk_ports = bitmap;
1465
1466 return BFA_STATUS_OK;
1467 }
1468
1469 void
1470 bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
1471 {
1472 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1473
1474 qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
1475 qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
1476 }
1477
1478 void
1479 bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
1480 struct bfa_qos_vc_attr_s *qos_vc_attr)
1481 {
1482 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1483 struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
1484 u32 i = 0;
1485
1486 qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
1487 qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit);
1488 qos_vc_attr->elp_opmode_flags =
1489 bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
1490
1491 /*
1492 * Individual VC info
1493 */
1494 while (i < qos_vc_attr->total_vc_count) {
1495 qos_vc_attr->vc_info[i].vc_credit =
1496 bfa_vc_attr->vc_info[i].vc_credit;
1497 qos_vc_attr->vc_info[i].borrow_credit =
1498 bfa_vc_attr->vc_info[i].borrow_credit;
1499 qos_vc_attr->vc_info[i].priority =
1500 bfa_vc_attr->vc_info[i].priority;
1501 ++i;
1502 }
1503 }
1504
1505 /**
1506 * Fetch QoS Stats.
1507 */
1508 bfa_status_t
1509 bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1510 bfa_cb_pport_t cbfn, void *cbarg)
1511 {
1512 /*
1513 * QoS stats is embedded in port stats
1514 */
1515 return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
1516 }
1517
1518 bfa_status_t
1519 bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1520 {
1521 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1522
1523 if (port->stats_busy) {
1524 bfa_trc(bfa, port->stats_busy);
1525 return BFA_STATUS_DEVBUSY;
1526 }
1527
1528 port->stats_busy = BFA_TRUE;
1529 port->stats_cbfn = cbfn;
1530 port->stats_cbarg = cbarg;
1531
1532 bfa_port_qos_stats_clear(port);
1533
1534 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1535 BFA_PORT_STATS_TOV);
1536 return BFA_STATUS_OK;
1537 }
1538
1539 /**
1540 * Fetch port attributes.
1541 */
1542 bfa_status_t
1543 bfa_pport_trunk_disable(struct bfa_s *bfa)
1544 {
1545 return BFA_STATUS_OK;
1546 }
1547
1548 bfa_boolean_t
1549 bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
1550 {
1551 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1552
1553 *bitmap = port->cfg.trunk_ports;
1554 return port->cfg.trunked;
1555 }
1556
1557 bfa_boolean_t
1558 bfa_pport_is_disabled(struct bfa_s *bfa)
1559 {
1560 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1561
1562 return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
1563 BFA_PPORT_ST_DISABLED;
1564
1565 }
1566
1567 bfa_boolean_t
1568 bfa_pport_is_ratelim(struct bfa_s *bfa)
1569 {
1570 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1571
1572 return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
1573
1574 }
1575
1576 void
1577 bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
1578 {
1579 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1580
1581 bfa_trc(bfa, on_off);
1582 bfa_trc(bfa, pport->cfg.qos_enabled);
1583
1584 pport->cfg.qos_enabled = on_off;
1585 }
1586
1587 void
1588 bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
1589 {
1590 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1591
1592 bfa_trc(bfa, on_off);
1593 bfa_trc(bfa, pport->cfg.ratelimit);
1594
1595 pport->cfg.ratelimit = on_off;
1596 if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
1597 pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
1598 }
1599
1600 /**
1601 * Configure default minimum ratelim speed
1602 */
1603 bfa_status_t
1604 bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1605 {
1606 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1607
1608 bfa_trc(bfa, speed);
1609
1610 /*
1611 * Auto and speeds greater than the supported speed, are invalid
1612 */
1613 if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
1614 bfa_trc(bfa, pport->speed_sup);
1615 return BFA_STATUS_UNSUPP_SPEED;
1616 }
1617
1618 pport->cfg.trl_def_speed = speed;
1619
1620 return BFA_STATUS_OK;
1621 }
1622
1623 /**
1624 * Get default minimum ratelim speed
1625 */
1626 enum bfa_pport_speed
1627 bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
1628 {
1629 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1630
1631 bfa_trc(bfa, pport->cfg.trl_def_speed);
1632 return pport->cfg.trl_def_speed;
1633
1634 }
1635
1636 void
1637 bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
1638 {
1639 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1640
1641 bfa_trc(bfa, status);
1642 bfa_trc(bfa, pport->diag_busy);
1643
1644 pport->diag_busy = status;
1645 }
1646
1647 void
1648 bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
1649 bfa_boolean_t link_e2e_beacon)
1650 {
1651 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1652
1653 bfa_trc(bfa, beacon);
1654 bfa_trc(bfa, link_e2e_beacon);
1655 bfa_trc(bfa, pport->beacon);
1656 bfa_trc(bfa, pport->link_e2e_beacon);
1657
1658 pport->beacon = beacon;
1659 pport->link_e2e_beacon = link_e2e_beacon;
1660 }
1661
1662 bfa_boolean_t
1663 bfa_pport_is_linkup(struct bfa_s *bfa)
1664 {
1665 return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
1666 }
1667
1668
This page took 0.087753 seconds and 5 git commands to generate.