diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-11-03 15:14:39 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-11-03 15:14:39 -0500 |
commit | 2058297d2d045cb57138c33b87cfabcc80e65186 (patch) | |
tree | 7ccffd0e162cbd7471f643561e79f23abb989a62 /drivers/scsi/bfa/bfa_fcport.c | |
parent | 150e6c67f4bf6ab51e62defc41bd19a2eefe5709 (diff) | |
parent | 4b27e1bb442e964903f8a3fa6bdf33a602dc0941 (diff) |
Merge branch 'for-linus' into for-2.6.33
Conflicts:
block/cfq-iosched.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcport.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcport.c | 1671 |
1 files changed, 1671 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c new file mode 100644 index 000000000000..992435987deb --- /dev/null +++ b/drivers/scsi/bfa/bfa_fcport.c | |||
@@ -0,0 +1,1671 @@ | |||
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 | } | ||
396 | break; | ||
397 | |||
398 | case BFA_PPORT_SM_STOP: | ||
399 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | ||
400 | bfa_pport_reset_linkinfo(pport); | ||
401 | if (BFA_PORT_IS_DISABLED(pport->bfa)) { | ||
402 | bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); | ||
403 | } else { | ||
404 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); | ||
405 | } | ||
406 | break; | ||
407 | |||
408 | case BFA_PPORT_SM_HWFAIL: | ||
409 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | ||
410 | bfa_pport_reset_linkinfo(pport); | ||
411 | bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); | ||
412 | if (BFA_PORT_IS_DISABLED(pport->bfa)) { | ||
413 | bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); | ||
414 | } else { | ||
415 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); | ||
416 | } | ||
417 | break; | ||
418 | |||
419 | default: | ||
420 | bfa_sm_fault(pport->bfa, event); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | static void | ||
425 | bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, | ||
426 | enum bfa_pport_sm_event event) | ||
427 | { | ||
428 | bfa_trc(pport->bfa, event); | ||
429 | |||
430 | switch (event) { | ||
431 | case BFA_PPORT_SM_QRESUME: | ||
432 | bfa_sm_set_state(pport, bfa_pport_sm_disabling); | ||
433 | bfa_pport_send_disable(pport); | ||
434 | break; | ||
435 | |||
436 | case BFA_PPORT_SM_STOP: | ||
437 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | ||
438 | bfa_reqq_wcancel(&pport->reqq_wait); | ||
439 | break; | ||
440 | |||
441 | case BFA_PPORT_SM_DISABLE: | ||
442 | /** | ||
443 | * Already being disabled. | ||
444 | */ | ||
445 | break; | ||
446 | |||
447 | case BFA_PPORT_SM_LINKUP: | ||
448 | case BFA_PPORT_SM_LINKDOWN: | ||
449 | /** | ||
450 | * Possible to get link events when doing back-to-back | ||
451 | * enable/disables. | ||
452 | */ | ||
453 | break; | ||
454 | |||
455 | case BFA_PPORT_SM_HWFAIL: | ||
456 | bfa_sm_set_state(pport, bfa_pport_sm_iocfail); | ||
457 | bfa_reqq_wcancel(&pport->reqq_wait); | ||
458 | break; | ||
459 | |||
460 | default: | ||
461 | bfa_sm_fault(pport->bfa, event); | ||
462 | } | ||
463 | } | ||
464 | |||
465 | static void | ||
466 | bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | ||
467 | { | ||
468 | bfa_trc(pport->bfa, event); | ||
469 | |||
470 | switch (event) { | ||
471 | case BFA_PPORT_SM_FWRSP: | ||
472 | bfa_sm_set_state(pport, bfa_pport_sm_disabled); | ||
473 | break; | ||
474 | |||
475 | case BFA_PPORT_SM_DISABLE: | ||
476 | /** | ||
477 | * Already being disabled. | ||
478 | */ | ||
479 | break; | ||
480 | |||
481 | case BFA_PPORT_SM_ENABLE: | ||
482 | if (bfa_pport_send_enable(pport)) | ||
483 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | ||
484 | else | ||
485 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | ||
486 | |||
487 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | ||
488 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); | ||
489 | bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); | ||
490 | break; | ||
491 | |||
492 | case BFA_PPORT_SM_STOP: | ||
493 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | ||
494 | break; | ||
495 | |||
496 | case BFA_PPORT_SM_LINKUP: | ||
497 | case BFA_PPORT_SM_LINKDOWN: | ||
498 | /** | ||
499 | * Possible to get link events when doing back-to-back | ||
500 | * enable/disables. | ||
501 | */ | ||
502 | break; | ||
503 | |||
504 | case BFA_PPORT_SM_HWFAIL: | ||
505 | bfa_sm_set_state(pport, bfa_pport_sm_iocfail); | ||
506 | break; | ||
507 | |||
508 | default: | ||
509 | bfa_sm_fault(pport->bfa, event); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | static void | ||
514 | bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | ||
515 | { | ||
516 | bfa_trc(pport->bfa, event); | ||
517 | |||
518 | switch (event) { | ||
519 | case BFA_PPORT_SM_START: | ||
520 | /** | ||
521 | * Ignore start event for a port that is disabled. | ||
522 | */ | ||
523 | break; | ||
524 | |||
525 | case BFA_PPORT_SM_STOP: | ||
526 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | ||
527 | break; | ||
528 | |||
529 | case BFA_PPORT_SM_ENABLE: | ||
530 | if (bfa_pport_send_enable(pport)) | ||
531 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | ||
532 | else | ||
533 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | ||
534 | |||
535 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | ||
536 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); | ||
537 | bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); | ||
538 | break; | ||
539 | |||
540 | case BFA_PPORT_SM_DISABLE: | ||
541 | /** | ||
542 | * Already disabled. | ||
543 | */ | ||
544 | break; | ||
545 | |||
546 | case BFA_PPORT_SM_HWFAIL: | ||
547 | bfa_sm_set_state(pport, bfa_pport_sm_iocfail); | ||
548 | break; | ||
549 | |||
550 | default: | ||
551 | bfa_sm_fault(pport->bfa, event); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | static void | ||
556 | bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | ||
557 | { | ||
558 | bfa_trc(pport->bfa, event); | ||
559 | |||
560 | switch (event) { | ||
561 | case BFA_PPORT_SM_START: | ||
562 | if (bfa_pport_send_enable(pport)) | ||
563 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | ||
564 | else | ||
565 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | ||
566 | break; | ||
567 | |||
568 | default: | ||
569 | /** | ||
570 | * Ignore all other events. | ||
571 | */ | ||
572 | ; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * Port is enabled. IOC is down/failed. | ||
578 | */ | ||
579 | static void | ||
580 | bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | ||
581 | { | ||
582 | bfa_trc(pport->bfa, event); | ||
583 | |||
584 | switch (event) { | ||
585 | case BFA_PPORT_SM_START: | ||
586 | if (bfa_pport_send_enable(pport)) | ||
587 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | ||
588 | else | ||
589 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | ||
590 | break; | ||
591 | |||
592 | default: | ||
593 | /** | ||
594 | * Ignore all events. | ||
595 | */ | ||
596 | ; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | /** | ||
601 | * Port is disabled. IOC is down/failed. | ||
602 | */ | ||
603 | static void | ||
604 | bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | ||
605 | { | ||
606 | bfa_trc(pport->bfa, event); | ||
607 | |||
608 | switch (event) { | ||
609 | case BFA_PPORT_SM_START: | ||
610 | bfa_sm_set_state(pport, bfa_pport_sm_disabled); | ||
611 | break; | ||
612 | |||
613 | case BFA_PPORT_SM_ENABLE: | ||
614 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | ||
615 | break; | ||
616 | |||
617 | default: | ||
618 | /** | ||
619 | * Ignore all events. | ||
620 | */ | ||
621 | ; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | |||
626 | |||
627 | /** | ||
628 | * bfa_pport_private | ||
629 | */ | ||
630 | |||
631 | static void | ||
632 | __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) | ||
633 | { | ||
634 | struct bfa_pport_s *pport = cbarg; | ||
635 | |||
636 | if (complete) | ||
637 | pport->event_cbfn(pport->event_cbarg, pport->hcb_event); | ||
638 | } | ||
639 | |||
640 | #define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ | ||
641 | BFA_CACHELINE_SZ)) | ||
642 | |||
643 | static void | ||
644 | bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, | ||
645 | u32 *dm_len) | ||
646 | { | ||
647 | *dm_len += PPORT_STATS_DMA_SZ; | ||
648 | } | ||
649 | |||
650 | static void | ||
651 | bfa_pport_qresume(void *cbarg) | ||
652 | { | ||
653 | struct bfa_pport_s *port = cbarg; | ||
654 | |||
655 | bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME); | ||
656 | } | ||
657 | |||
658 | static void | ||
659 | bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) | ||
660 | { | ||
661 | u8 *dm_kva; | ||
662 | u64 dm_pa; | ||
663 | |||
664 | dm_kva = bfa_meminfo_dma_virt(meminfo); | ||
665 | dm_pa = bfa_meminfo_dma_phys(meminfo); | ||
666 | |||
667 | pport->stats_kva = dm_kva; | ||
668 | pport->stats_pa = dm_pa; | ||
669 | pport->stats = (union bfa_pport_stats_u *)dm_kva; | ||
670 | |||
671 | dm_kva += PPORT_STATS_DMA_SZ; | ||
672 | dm_pa += PPORT_STATS_DMA_SZ; | ||
673 | |||
674 | bfa_meminfo_dma_virt(meminfo) = dm_kva; | ||
675 | bfa_meminfo_dma_phys(meminfo) = dm_pa; | ||
676 | } | ||
677 | |||
678 | /** | ||
679 | * Memory initialization. | ||
680 | */ | ||
681 | static void | ||
682 | bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | ||
683 | struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) | ||
684 | { | ||
685 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
686 | struct bfa_pport_cfg_s *port_cfg = &pport->cfg; | ||
687 | |||
688 | bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); | ||
689 | pport->bfa = bfa; | ||
690 | |||
691 | bfa_pport_mem_claim(pport, meminfo); | ||
692 | |||
693 | bfa_sm_set_state(pport, bfa_pport_sm_uninit); | ||
694 | |||
695 | /** | ||
696 | * initialize and set default configuration | ||
697 | */ | ||
698 | port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P; | ||
699 | port_cfg->speed = BFA_PPORT_SPEED_AUTO; | ||
700 | port_cfg->trunked = BFA_FALSE; | ||
701 | port_cfg->maxfrsize = 0; | ||
702 | |||
703 | port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS; | ||
704 | |||
705 | bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport); | ||
706 | } | ||
707 | |||
708 | static void | ||
709 | bfa_pport_initdone(struct bfa_s *bfa) | ||
710 | { | ||
711 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
712 | |||
713 | /** | ||
714 | * Initialize port attributes from IOC hardware data. | ||
715 | */ | ||
716 | bfa_pport_set_wwns(pport); | ||
717 | if (pport->cfg.maxfrsize == 0) | ||
718 | pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); | ||
719 | pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); | ||
720 | pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); | ||
721 | |||
722 | bfa_assert(pport->cfg.maxfrsize); | ||
723 | bfa_assert(pport->cfg.rx_bbcredit); | ||
724 | bfa_assert(pport->speed_sup); | ||
725 | } | ||
726 | |||
727 | static void | ||
728 | bfa_pport_detach(struct bfa_s *bfa) | ||
729 | { | ||
730 | } | ||
731 | |||
732 | /** | ||
733 | * Called when IOC is ready. | ||
734 | */ | ||
735 | static void | ||
736 | bfa_pport_start(struct bfa_s *bfa) | ||
737 | { | ||
738 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START); | ||
739 | } | ||
740 | |||
741 | /** | ||
742 | * Called before IOC is stopped. | ||
743 | */ | ||
744 | static void | ||
745 | bfa_pport_stop(struct bfa_s *bfa) | ||
746 | { | ||
747 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP); | ||
748 | } | ||
749 | |||
750 | /** | ||
751 | * Called when IOC failure is detected. | ||
752 | */ | ||
753 | static void | ||
754 | bfa_pport_iocdisable(struct bfa_s *bfa) | ||
755 | { | ||
756 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL); | ||
757 | } | ||
758 | |||
759 | static void | ||
760 | bfa_pport_update_linkinfo(struct bfa_pport_s *pport) | ||
761 | { | ||
762 | struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event; | ||
763 | |||
764 | pport->speed = pevent->link_state.speed; | ||
765 | pport->topology = pevent->link_state.topology; | ||
766 | |||
767 | if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP) | ||
768 | pport->myalpa = pevent->link_state.tl.loop_info.myalpa; | ||
769 | |||
770 | /* | ||
771 | * QoS Details | ||
772 | */ | ||
773 | bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr); | ||
774 | bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr); | ||
775 | |||
776 | bfa_trc(pport->bfa, pport->speed); | ||
777 | bfa_trc(pport->bfa, pport->topology); | ||
778 | } | ||
779 | |||
780 | static void | ||
781 | bfa_pport_reset_linkinfo(struct bfa_pport_s *pport) | ||
782 | { | ||
783 | pport->speed = BFA_PPORT_SPEED_UNKNOWN; | ||
784 | pport->topology = BFA_PPORT_TOPOLOGY_NONE; | ||
785 | } | ||
786 | |||
787 | /** | ||
788 | * Send port enable message to firmware. | ||
789 | */ | ||
790 | static bfa_boolean_t | ||
791 | bfa_pport_send_enable(struct bfa_pport_s *port) | ||
792 | { | ||
793 | struct bfi_pport_enable_req_s *m; | ||
794 | |||
795 | /** | ||
796 | * Increment message tag before queue check, so that responses to old | ||
797 | * requests are discarded. | ||
798 | */ | ||
799 | port->msgtag++; | ||
800 | |||
801 | /** | ||
802 | * check for room in queue to send request now | ||
803 | */ | ||
804 | m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
805 | if (!m) { | ||
806 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); | ||
807 | return BFA_FALSE; | ||
808 | } | ||
809 | |||
810 | bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ, | ||
811 | bfa_lpuid(port->bfa)); | ||
812 | m->nwwn = port->nwwn; | ||
813 | m->pwwn = port->pwwn; | ||
814 | m->port_cfg = port->cfg; | ||
815 | m->msgtag = port->msgtag; | ||
816 | m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize); | ||
817 | bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa); | ||
818 | bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo); | ||
819 | bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi); | ||
820 | |||
821 | /** | ||
822 | * queue I/O message to firmware | ||
823 | */ | ||
824 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
825 | return BFA_TRUE; | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * Send port disable message to firmware. | ||
830 | */ | ||
831 | static bfa_boolean_t | ||
832 | bfa_pport_send_disable(struct bfa_pport_s *port) | ||
833 | { | ||
834 | bfi_pport_disable_req_t *m; | ||
835 | |||
836 | /** | ||
837 | * Increment message tag before queue check, so that responses to old | ||
838 | * requests are discarded. | ||
839 | */ | ||
840 | port->msgtag++; | ||
841 | |||
842 | /** | ||
843 | * check for room in queue to send request now | ||
844 | */ | ||
845 | m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
846 | if (!m) { | ||
847 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); | ||
848 | return BFA_FALSE; | ||
849 | } | ||
850 | |||
851 | bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ, | ||
852 | bfa_lpuid(port->bfa)); | ||
853 | m->msgtag = port->msgtag; | ||
854 | |||
855 | /** | ||
856 | * queue I/O message to firmware | ||
857 | */ | ||
858 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
859 | |||
860 | return BFA_TRUE; | ||
861 | } | ||
862 | |||
863 | static void | ||
864 | bfa_pport_set_wwns(struct bfa_pport_s *port) | ||
865 | { | ||
866 | port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc); | ||
867 | port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc); | ||
868 | |||
869 | bfa_trc(port->bfa, port->pwwn); | ||
870 | bfa_trc(port->bfa, port->nwwn); | ||
871 | } | ||
872 | |||
873 | static void | ||
874 | bfa_port_send_txcredit(void *port_cbarg) | ||
875 | { | ||
876 | |||
877 | struct bfa_pport_s *port = port_cbarg; | ||
878 | struct bfi_pport_set_svc_params_req_s *m; | ||
879 | |||
880 | /** | ||
881 | * check for room in queue to send request now | ||
882 | */ | ||
883 | m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
884 | if (!m) { | ||
885 | bfa_trc(port->bfa, port->cfg.tx_bbcredit); | ||
886 | return; | ||
887 | } | ||
888 | |||
889 | bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ, | ||
890 | bfa_lpuid(port->bfa)); | ||
891 | m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit); | ||
892 | |||
893 | /** | ||
894 | * queue I/O message to firmware | ||
895 | */ | ||
896 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
897 | } | ||
898 | |||
899 | |||
900 | |||
901 | /** | ||
902 | * bfa_pport_public | ||
903 | */ | ||
904 | |||
905 | /** | ||
906 | * Firmware message handler. | ||
907 | */ | ||
908 | void | ||
909 | bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | ||
910 | { | ||
911 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
912 | union bfi_pport_i2h_msg_u i2hmsg; | ||
913 | |||
914 | i2hmsg.msg = msg; | ||
915 | pport->event_arg.i2hmsg = i2hmsg; | ||
916 | |||
917 | switch (msg->mhdr.msg_id) { | ||
918 | case BFI_PPORT_I2H_ENABLE_RSP: | ||
919 | if (pport->msgtag == i2hmsg.enable_rsp->msgtag) | ||
920 | bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); | ||
921 | break; | ||
922 | |||
923 | case BFI_PPORT_I2H_DISABLE_RSP: | ||
924 | if (pport->msgtag == i2hmsg.enable_rsp->msgtag) | ||
925 | bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); | ||
926 | break; | ||
927 | |||
928 | case BFI_PPORT_I2H_EVENT: | ||
929 | switch (i2hmsg.event->link_state.linkstate) { | ||
930 | case BFA_PPORT_LINKUP: | ||
931 | bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP); | ||
932 | break; | ||
933 | case BFA_PPORT_LINKDOWN: | ||
934 | bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN); | ||
935 | break; | ||
936 | case BFA_PPORT_TRUNK_LINKDOWN: | ||
937 | /** todo: event notification */ | ||
938 | break; | ||
939 | } | ||
940 | break; | ||
941 | |||
942 | case BFI_PPORT_I2H_GET_STATS_RSP: | ||
943 | case BFI_PPORT_I2H_GET_QOS_STATS_RSP: | ||
944 | /* | ||
945 | * check for timer pop before processing the rsp | ||
946 | */ | ||
947 | if (pport->stats_busy == BFA_FALSE | ||
948 | || pport->stats_status == BFA_STATUS_ETIMER) | ||
949 | break; | ||
950 | |||
951 | bfa_timer_stop(&pport->timer); | ||
952 | pport->stats_status = i2hmsg.getstats_rsp->status; | ||
953 | bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats, | ||
954 | pport); | ||
955 | break; | ||
956 | case BFI_PPORT_I2H_CLEAR_STATS_RSP: | ||
957 | case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP: | ||
958 | /* | ||
959 | * check for timer pop before processing the rsp | ||
960 | */ | ||
961 | if (pport->stats_busy == BFA_FALSE | ||
962 | || pport->stats_status == BFA_STATUS_ETIMER) | ||
963 | break; | ||
964 | |||
965 | bfa_timer_stop(&pport->timer); | ||
966 | pport->stats_status = BFA_STATUS_OK; | ||
967 | bfa_cb_queue(pport->bfa, &pport->hcb_qe, | ||
968 | __bfa_cb_port_stats_clr, pport); | ||
969 | break; | ||
970 | |||
971 | default: | ||
972 | bfa_assert(0); | ||
973 | } | ||
974 | } | ||
975 | |||
976 | |||
977 | |||
978 | /** | ||
979 | * bfa_pport_api | ||
980 | */ | ||
981 | |||
982 | /** | ||
983 | * Registered callback for port events. | ||
984 | */ | ||
985 | void | ||
986 | bfa_pport_event_register(struct bfa_s *bfa, | ||
987 | void (*cbfn) (void *cbarg, bfa_pport_event_t event), | ||
988 | void *cbarg) | ||
989 | { | ||
990 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
991 | |||
992 | pport->event_cbfn = cbfn; | ||
993 | pport->event_cbarg = cbarg; | ||
994 | } | ||
995 | |||
996 | bfa_status_t | ||
997 | bfa_pport_enable(struct bfa_s *bfa) | ||
998 | { | ||
999 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1000 | |||
1001 | if (pport->diag_busy) | ||
1002 | return (BFA_STATUS_DIAG_BUSY); | ||
1003 | else if (bfa_sm_cmp_state | ||
1004 | (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait)) | ||
1005 | return (BFA_STATUS_DEVBUSY); | ||
1006 | |||
1007 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE); | ||
1008 | return BFA_STATUS_OK; | ||
1009 | } | ||
1010 | |||
1011 | bfa_status_t | ||
1012 | bfa_pport_disable(struct bfa_s *bfa) | ||
1013 | { | ||
1014 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE); | ||
1015 | return BFA_STATUS_OK; | ||
1016 | } | ||
1017 | |||
1018 | /** | ||
1019 | * Configure port speed. | ||
1020 | */ | ||
1021 | bfa_status_t | ||
1022 | bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) | ||
1023 | { | ||
1024 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1025 | |||
1026 | bfa_trc(bfa, speed); | ||
1027 | |||
1028 | if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) { | ||
1029 | bfa_trc(bfa, pport->speed_sup); | ||
1030 | return BFA_STATUS_UNSUPP_SPEED; | ||
1031 | } | ||
1032 | |||
1033 | pport->cfg.speed = speed; | ||
1034 | |||
1035 | return (BFA_STATUS_OK); | ||
1036 | } | ||
1037 | |||
1038 | /** | ||
1039 | * Get current speed. | ||
1040 | */ | ||
1041 | enum bfa_pport_speed | ||
1042 | bfa_pport_get_speed(struct bfa_s *bfa) | ||
1043 | { | ||
1044 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1045 | |||
1046 | return port->speed; | ||
1047 | } | ||
1048 | |||
1049 | /** | ||
1050 | * Configure port topology. | ||
1051 | */ | ||
1052 | bfa_status_t | ||
1053 | bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) | ||
1054 | { | ||
1055 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1056 | |||
1057 | bfa_trc(bfa, topology); | ||
1058 | bfa_trc(bfa, pport->cfg.topology); | ||
1059 | |||
1060 | switch (topology) { | ||
1061 | case BFA_PPORT_TOPOLOGY_P2P: | ||
1062 | case BFA_PPORT_TOPOLOGY_LOOP: | ||
1063 | case BFA_PPORT_TOPOLOGY_AUTO: | ||
1064 | break; | ||
1065 | |||
1066 | default: | ||
1067 | return BFA_STATUS_EINVAL; | ||
1068 | } | ||
1069 | |||
1070 | pport->cfg.topology = topology; | ||
1071 | return (BFA_STATUS_OK); | ||
1072 | } | ||
1073 | |||
1074 | /** | ||
1075 | * Get current topology. | ||
1076 | */ | ||
1077 | enum bfa_pport_topology | ||
1078 | bfa_pport_get_topology(struct bfa_s *bfa) | ||
1079 | { | ||
1080 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1081 | |||
1082 | return port->topology; | ||
1083 | } | ||
1084 | |||
1085 | bfa_status_t | ||
1086 | bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) | ||
1087 | { | ||
1088 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1089 | |||
1090 | bfa_trc(bfa, alpa); | ||
1091 | bfa_trc(bfa, pport->cfg.cfg_hardalpa); | ||
1092 | bfa_trc(bfa, pport->cfg.hardalpa); | ||
1093 | |||
1094 | pport->cfg.cfg_hardalpa = BFA_TRUE; | ||
1095 | pport->cfg.hardalpa = alpa; | ||
1096 | |||
1097 | return (BFA_STATUS_OK); | ||
1098 | } | ||
1099 | |||
1100 | bfa_status_t | ||
1101 | bfa_pport_clr_hardalpa(struct bfa_s *bfa) | ||
1102 | { | ||
1103 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1104 | |||
1105 | bfa_trc(bfa, pport->cfg.cfg_hardalpa); | ||
1106 | bfa_trc(bfa, pport->cfg.hardalpa); | ||
1107 | |||
1108 | pport->cfg.cfg_hardalpa = BFA_FALSE; | ||
1109 | return (BFA_STATUS_OK); | ||
1110 | } | ||
1111 | |||
1112 | bfa_boolean_t | ||
1113 | bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) | ||
1114 | { | ||
1115 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1116 | |||
1117 | *alpa = port->cfg.hardalpa; | ||
1118 | return port->cfg.cfg_hardalpa; | ||
1119 | } | ||
1120 | |||
1121 | u8 | ||
1122 | bfa_pport_get_myalpa(struct bfa_s *bfa) | ||
1123 | { | ||
1124 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1125 | |||
1126 | return port->myalpa; | ||
1127 | } | ||
1128 | |||
1129 | bfa_status_t | ||
1130 | bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) | ||
1131 | { | ||
1132 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1133 | |||
1134 | bfa_trc(bfa, maxfrsize); | ||
1135 | bfa_trc(bfa, pport->cfg.maxfrsize); | ||
1136 | |||
1137 | /* | ||
1138 | * with in range | ||
1139 | */ | ||
1140 | if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ)) | ||
1141 | return (BFA_STATUS_INVLD_DFSZ); | ||
1142 | |||
1143 | /* | ||
1144 | * power of 2, if not the max frame size of 2112 | ||
1145 | */ | ||
1146 | if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) | ||
1147 | return (BFA_STATUS_INVLD_DFSZ); | ||
1148 | |||
1149 | pport->cfg.maxfrsize = maxfrsize; | ||
1150 | return (BFA_STATUS_OK); | ||
1151 | } | ||
1152 | |||
1153 | u16 | ||
1154 | bfa_pport_get_maxfrsize(struct bfa_s *bfa) | ||
1155 | { | ||
1156 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1157 | |||
1158 | return port->cfg.maxfrsize; | ||
1159 | } | ||
1160 | |||
1161 | u32 | ||
1162 | bfa_pport_mypid(struct bfa_s *bfa) | ||
1163 | { | ||
1164 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1165 | |||
1166 | return port->mypid; | ||
1167 | } | ||
1168 | |||
1169 | u8 | ||
1170 | bfa_pport_get_rx_bbcredit(struct bfa_s *bfa) | ||
1171 | { | ||
1172 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1173 | |||
1174 | return port->cfg.rx_bbcredit; | ||
1175 | } | ||
1176 | |||
1177 | void | ||
1178 | bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) | ||
1179 | { | ||
1180 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1181 | |||
1182 | port->cfg.tx_bbcredit = (u8) tx_bbcredit; | ||
1183 | bfa_port_send_txcredit(port); | ||
1184 | } | ||
1185 | |||
1186 | /** | ||
1187 | * Get port attributes. | ||
1188 | */ | ||
1189 | |||
1190 | wwn_t | ||
1191 | bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) | ||
1192 | { | ||
1193 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1194 | if (node) | ||
1195 | return pport->nwwn; | ||
1196 | else | ||
1197 | return pport->pwwn; | ||
1198 | } | ||
1199 | |||
1200 | void | ||
1201 | bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) | ||
1202 | { | ||
1203 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1204 | |||
1205 | bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); | ||
1206 | |||
1207 | attr->nwwn = pport->nwwn; | ||
1208 | attr->pwwn = pport->pwwn; | ||
1209 | |||
1210 | bfa_os_memcpy(&attr->pport_cfg, &pport->cfg, | ||
1211 | sizeof(struct bfa_pport_cfg_s)); | ||
1212 | /* | ||
1213 | * speed attributes | ||
1214 | */ | ||
1215 | attr->pport_cfg.speed = pport->cfg.speed; | ||
1216 | attr->speed_supported = pport->speed_sup; | ||
1217 | attr->speed = pport->speed; | ||
1218 | attr->cos_supported = FC_CLASS_3; | ||
1219 | |||
1220 | /* | ||
1221 | * topology attributes | ||
1222 | */ | ||
1223 | attr->pport_cfg.topology = pport->cfg.topology; | ||
1224 | attr->topology = pport->topology; | ||
1225 | |||
1226 | /* | ||
1227 | * beacon attributes | ||
1228 | */ | ||
1229 | attr->beacon = pport->beacon; | ||
1230 | attr->link_e2e_beacon = pport->link_e2e_beacon; | ||
1231 | attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog); | ||
1232 | |||
1233 | attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); | ||
1234 | attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); | ||
1235 | attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm); | ||
1236 | if (bfa_ioc_is_disabled(&pport->bfa->ioc)) | ||
1237 | attr->port_state = BFA_PPORT_ST_IOCDIS; | ||
1238 | else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc)) | ||
1239 | attr->port_state = BFA_PPORT_ST_FWMISMATCH; | ||
1240 | } | ||
1241 | |||
1242 | static void | ||
1243 | bfa_port_stats_query(void *cbarg) | ||
1244 | { | ||
1245 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1246 | bfi_pport_get_stats_req_t *msg; | ||
1247 | |||
1248 | msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
1249 | |||
1250 | if (!msg) { | ||
1251 | port->stats_qfull = BFA_TRUE; | ||
1252 | bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query, | ||
1253 | port); | ||
1254 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); | ||
1255 | return; | ||
1256 | } | ||
1257 | port->stats_qfull = BFA_FALSE; | ||
1258 | |||
1259 | bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); | ||
1260 | bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ, | ||
1261 | bfa_lpuid(port->bfa)); | ||
1262 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
1263 | |||
1264 | return; | ||
1265 | } | ||
1266 | |||
1267 | static void | ||
1268 | bfa_port_stats_clear(void *cbarg) | ||
1269 | { | ||
1270 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1271 | bfi_pport_clear_stats_req_t *msg; | ||
1272 | |||
1273 | msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
1274 | |||
1275 | if (!msg) { | ||
1276 | port->stats_qfull = BFA_TRUE; | ||
1277 | bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear, | ||
1278 | port); | ||
1279 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); | ||
1280 | return; | ||
1281 | } | ||
1282 | port->stats_qfull = BFA_FALSE; | ||
1283 | |||
1284 | bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); | ||
1285 | bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ, | ||
1286 | bfa_lpuid(port->bfa)); | ||
1287 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
1288 | return; | ||
1289 | } | ||
1290 | |||
1291 | static void | ||
1292 | bfa_port_qos_stats_clear(void *cbarg) | ||
1293 | { | ||
1294 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1295 | bfi_pport_clear_qos_stats_req_t *msg; | ||
1296 | |||
1297 | msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
1298 | |||
1299 | if (!msg) { | ||
1300 | port->stats_qfull = BFA_TRUE; | ||
1301 | bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear, | ||
1302 | port); | ||
1303 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); | ||
1304 | return; | ||
1305 | } | ||
1306 | port->stats_qfull = BFA_FALSE; | ||
1307 | |||
1308 | bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t)); | ||
1309 | bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, | ||
1310 | bfa_lpuid(port->bfa)); | ||
1311 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
1312 | return; | ||
1313 | } | ||
1314 | |||
1315 | static void | ||
1316 | bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) | ||
1317 | { | ||
1318 | u32 *dip = (u32 *) d; | ||
1319 | u32 *sip = (u32 *) s; | ||
1320 | int i; | ||
1321 | |||
1322 | /* | ||
1323 | * Do 64 bit fields swap first | ||
1324 | */ | ||
1325 | for (i = 0; | ||
1326 | i < | ||
1327 | ((sizeof(union bfa_pport_stats_u) - | ||
1328 | sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) { | ||
1329 | #ifdef __BIGENDIAN | ||
1330 | dip[i] = bfa_os_ntohl(sip[i]); | ||
1331 | dip[i + 1] = bfa_os_ntohl(sip[i + 1]); | ||
1332 | #else | ||
1333 | dip[i] = bfa_os_ntohl(sip[i + 1]); | ||
1334 | dip[i + 1] = bfa_os_ntohl(sip[i]); | ||
1335 | #endif | ||
1336 | } | ||
1337 | |||
1338 | /* | ||
1339 | * Now swap the 32 bit fields | ||
1340 | */ | ||
1341 | for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i) | ||
1342 | dip[i] = bfa_os_ntohl(sip[i]); | ||
1343 | } | ||
1344 | |||
1345 | static void | ||
1346 | __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete) | ||
1347 | { | ||
1348 | struct bfa_pport_s *port = cbarg; | ||
1349 | |||
1350 | if (complete) { | ||
1351 | port->stats_cbfn(port->stats_cbarg, port->stats_status); | ||
1352 | } else { | ||
1353 | port->stats_busy = BFA_FALSE; | ||
1354 | port->stats_status = BFA_STATUS_OK; | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | static void | ||
1359 | bfa_port_stats_clr_timeout(void *cbarg) | ||
1360 | { | ||
1361 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1362 | |||
1363 | bfa_trc(port->bfa, port->stats_qfull); | ||
1364 | |||
1365 | if (port->stats_qfull) { | ||
1366 | bfa_reqq_wcancel(&port->stats_reqq_wait); | ||
1367 | port->stats_qfull = BFA_FALSE; | ||
1368 | } | ||
1369 | |||
1370 | port->stats_status = BFA_STATUS_ETIMER; | ||
1371 | bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port); | ||
1372 | } | ||
1373 | |||
1374 | static void | ||
1375 | __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) | ||
1376 | { | ||
1377 | struct bfa_pport_s *port = cbarg; | ||
1378 | |||
1379 | if (complete) { | ||
1380 | if (port->stats_status == BFA_STATUS_OK) | ||
1381 | bfa_pport_stats_swap(port->stats_ret, port->stats); | ||
1382 | port->stats_cbfn(port->stats_cbarg, port->stats_status); | ||
1383 | } else { | ||
1384 | port->stats_busy = BFA_FALSE; | ||
1385 | port->stats_status = BFA_STATUS_OK; | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | static void | ||
1390 | bfa_port_stats_timeout(void *cbarg) | ||
1391 | { | ||
1392 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1393 | |||
1394 | bfa_trc(port->bfa, port->stats_qfull); | ||
1395 | |||
1396 | if (port->stats_qfull) { | ||
1397 | bfa_reqq_wcancel(&port->stats_reqq_wait); | ||
1398 | port->stats_qfull = BFA_FALSE; | ||
1399 | } | ||
1400 | |||
1401 | port->stats_status = BFA_STATUS_ETIMER; | ||
1402 | bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port); | ||
1403 | } | ||
1404 | |||
1405 | #define BFA_PORT_STATS_TOV 1000 | ||
1406 | |||
1407 | /** | ||
1408 | * Fetch port attributes. | ||
1409 | */ | ||
1410 | bfa_status_t | ||
1411 | bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, | ||
1412 | bfa_cb_pport_t cbfn, void *cbarg) | ||
1413 | { | ||
1414 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1415 | |||
1416 | if (port->stats_busy) { | ||
1417 | bfa_trc(bfa, port->stats_busy); | ||
1418 | return (BFA_STATUS_DEVBUSY); | ||
1419 | } | ||
1420 | |||
1421 | port->stats_busy = BFA_TRUE; | ||
1422 | port->stats_ret = stats; | ||
1423 | port->stats_cbfn = cbfn; | ||
1424 | port->stats_cbarg = cbarg; | ||
1425 | |||
1426 | bfa_port_stats_query(port); | ||
1427 | |||
1428 | bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port, | ||
1429 | BFA_PORT_STATS_TOV); | ||
1430 | return (BFA_STATUS_OK); | ||
1431 | } | ||
1432 | |||
1433 | bfa_status_t | ||
1434 | bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) | ||
1435 | { | ||
1436 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1437 | |||
1438 | if (port->stats_busy) { | ||
1439 | bfa_trc(bfa, port->stats_busy); | ||
1440 | return (BFA_STATUS_DEVBUSY); | ||
1441 | } | ||
1442 | |||
1443 | port->stats_busy = BFA_TRUE; | ||
1444 | port->stats_cbfn = cbfn; | ||
1445 | port->stats_cbarg = cbarg; | ||
1446 | |||
1447 | bfa_port_stats_clear(port); | ||
1448 | |||
1449 | bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, | ||
1450 | BFA_PORT_STATS_TOV); | ||
1451 | return (BFA_STATUS_OK); | ||
1452 | } | ||
1453 | |||
1454 | bfa_status_t | ||
1455 | bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap) | ||
1456 | { | ||
1457 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1458 | |||
1459 | bfa_trc(bfa, bitmap); | ||
1460 | bfa_trc(bfa, pport->cfg.trunked); | ||
1461 | bfa_trc(bfa, pport->cfg.trunk_ports); | ||
1462 | |||
1463 | if (!bitmap || (bitmap & (bitmap - 1))) | ||
1464 | return BFA_STATUS_EINVAL; | ||
1465 | |||
1466 | pport->cfg.trunked = BFA_TRUE; | ||
1467 | pport->cfg.trunk_ports = bitmap; | ||
1468 | |||
1469 | return BFA_STATUS_OK; | ||
1470 | } | ||
1471 | |||
1472 | void | ||
1473 | bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) | ||
1474 | { | ||
1475 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1476 | |||
1477 | qos_attr->state = bfa_os_ntohl(pport->qos_attr.state); | ||
1478 | qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr); | ||
1479 | } | ||
1480 | |||
1481 | void | ||
1482 | bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, | ||
1483 | struct bfa_qos_vc_attr_s *qos_vc_attr) | ||
1484 | { | ||
1485 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1486 | struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr; | ||
1487 | u32 i = 0; | ||
1488 | |||
1489 | qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); | ||
1490 | qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit); | ||
1491 | qos_vc_attr->elp_opmode_flags = | ||
1492 | bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags); | ||
1493 | |||
1494 | /* | ||
1495 | * Individual VC info | ||
1496 | */ | ||
1497 | while (i < qos_vc_attr->total_vc_count) { | ||
1498 | qos_vc_attr->vc_info[i].vc_credit = | ||
1499 | bfa_vc_attr->vc_info[i].vc_credit; | ||
1500 | qos_vc_attr->vc_info[i].borrow_credit = | ||
1501 | bfa_vc_attr->vc_info[i].borrow_credit; | ||
1502 | qos_vc_attr->vc_info[i].priority = | ||
1503 | bfa_vc_attr->vc_info[i].priority; | ||
1504 | ++i; | ||
1505 | } | ||
1506 | } | ||
1507 | |||
1508 | /** | ||
1509 | * Fetch QoS Stats. | ||
1510 | */ | ||
1511 | bfa_status_t | ||
1512 | bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, | ||
1513 | bfa_cb_pport_t cbfn, void *cbarg) | ||
1514 | { | ||
1515 | /* | ||
1516 | * QoS stats is embedded in port stats | ||
1517 | */ | ||
1518 | return (bfa_pport_get_stats(bfa, stats, cbfn, cbarg)); | ||
1519 | } | ||
1520 | |||
1521 | bfa_status_t | ||
1522 | bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) | ||
1523 | { | ||
1524 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1525 | |||
1526 | if (port->stats_busy) { | ||
1527 | bfa_trc(bfa, port->stats_busy); | ||
1528 | return (BFA_STATUS_DEVBUSY); | ||
1529 | } | ||
1530 | |||
1531 | port->stats_busy = BFA_TRUE; | ||
1532 | port->stats_cbfn = cbfn; | ||
1533 | port->stats_cbarg = cbarg; | ||
1534 | |||
1535 | bfa_port_qos_stats_clear(port); | ||
1536 | |||
1537 | bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, | ||
1538 | BFA_PORT_STATS_TOV); | ||
1539 | return (BFA_STATUS_OK); | ||
1540 | } | ||
1541 | |||
1542 | /** | ||
1543 | * Fetch port attributes. | ||
1544 | */ | ||
1545 | bfa_status_t | ||
1546 | bfa_pport_trunk_disable(struct bfa_s *bfa) | ||
1547 | { | ||
1548 | return (BFA_STATUS_OK); | ||
1549 | } | ||
1550 | |||
1551 | bfa_boolean_t | ||
1552 | bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap) | ||
1553 | { | ||
1554 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1555 | |||
1556 | *bitmap = port->cfg.trunk_ports; | ||
1557 | return port->cfg.trunked; | ||
1558 | } | ||
1559 | |||
1560 | bfa_boolean_t | ||
1561 | bfa_pport_is_disabled(struct bfa_s *bfa) | ||
1562 | { | ||
1563 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1564 | |||
1565 | return (bfa_sm_to_state(hal_pport_sm_table, port->sm) == | ||
1566 | BFA_PPORT_ST_DISABLED); | ||
1567 | |||
1568 | } | ||
1569 | |||
1570 | bfa_boolean_t | ||
1571 | bfa_pport_is_ratelim(struct bfa_s *bfa) | ||
1572 | { | ||
1573 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1574 | |||
1575 | return (pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE); | ||
1576 | |||
1577 | } | ||
1578 | |||
1579 | void | ||
1580 | bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) | ||
1581 | { | ||
1582 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1583 | |||
1584 | bfa_trc(bfa, on_off); | ||
1585 | bfa_trc(bfa, pport->cfg.qos_enabled); | ||
1586 | |||
1587 | pport->cfg.qos_enabled = on_off; | ||
1588 | } | ||
1589 | |||
1590 | void | ||
1591 | bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) | ||
1592 | { | ||
1593 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1594 | |||
1595 | bfa_trc(bfa, on_off); | ||
1596 | bfa_trc(bfa, pport->cfg.ratelimit); | ||
1597 | |||
1598 | pport->cfg.ratelimit = on_off; | ||
1599 | if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) | ||
1600 | pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; | ||
1601 | } | ||
1602 | |||
1603 | /** | ||
1604 | * Configure default minimum ratelim speed | ||
1605 | */ | ||
1606 | bfa_status_t | ||
1607 | bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) | ||
1608 | { | ||
1609 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1610 | |||
1611 | bfa_trc(bfa, speed); | ||
1612 | |||
1613 | /* | ||
1614 | * Auto and speeds greater than the supported speed, are invalid | ||
1615 | */ | ||
1616 | if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) { | ||
1617 | bfa_trc(bfa, pport->speed_sup); | ||
1618 | return BFA_STATUS_UNSUPP_SPEED; | ||
1619 | } | ||
1620 | |||
1621 | pport->cfg.trl_def_speed = speed; | ||
1622 | |||
1623 | return (BFA_STATUS_OK); | ||
1624 | } | ||
1625 | |||
1626 | /** | ||
1627 | * Get default minimum ratelim speed | ||
1628 | */ | ||
1629 | enum bfa_pport_speed | ||
1630 | bfa_pport_get_ratelim_speed(struct bfa_s *bfa) | ||
1631 | { | ||
1632 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1633 | |||
1634 | bfa_trc(bfa, pport->cfg.trl_def_speed); | ||
1635 | return (pport->cfg.trl_def_speed); | ||
1636 | |||
1637 | } | ||
1638 | |||
1639 | void | ||
1640 | bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status) | ||
1641 | { | ||
1642 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1643 | |||
1644 | bfa_trc(bfa, status); | ||
1645 | bfa_trc(bfa, pport->diag_busy); | ||
1646 | |||
1647 | pport->diag_busy = status; | ||
1648 | } | ||
1649 | |||
1650 | void | ||
1651 | bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, | ||
1652 | bfa_boolean_t link_e2e_beacon) | ||
1653 | { | ||
1654 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | ||
1655 | |||
1656 | bfa_trc(bfa, beacon); | ||
1657 | bfa_trc(bfa, link_e2e_beacon); | ||
1658 | bfa_trc(bfa, pport->beacon); | ||
1659 | bfa_trc(bfa, pport->link_e2e_beacon); | ||
1660 | |||
1661 | pport->beacon = beacon; | ||
1662 | pport->link_e2e_beacon = link_e2e_beacon; | ||
1663 | } | ||
1664 | |||
1665 | bfa_boolean_t | ||
1666 | bfa_pport_is_linkup(struct bfa_s *bfa) | ||
1667 | { | ||
1668 | return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup); | ||
1669 | } | ||
1670 | |||
1671 | |||